@tostudy-ai/cli 0.14.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/dist/cli.js +861 -627
- 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 });
|
|
2060
2206
|
return written;
|
|
2061
2207
|
}
|
|
2062
|
-
|
|
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 });
|
|
2214
|
+
return written;
|
|
2215
|
+
}
|
|
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
|
|
|
@@ -2995,14 +3141,14 @@ var init_doctor = __esm({
|
|
|
2995
3141
|
git: null
|
|
2996
3142
|
};
|
|
2997
3143
|
try {
|
|
2998
|
-
const { execFileSync:
|
|
2999
|
-
envChecks["pnpm"] =
|
|
3144
|
+
const { execFileSync: execFileSync4 } = await import("node:child_process");
|
|
3145
|
+
envChecks["pnpm"] = execFileSync4("pnpm", ["--version"], { encoding: "utf-8" }).trim();
|
|
3000
3146
|
} catch {
|
|
3001
3147
|
envChecks["pnpm"] = null;
|
|
3002
3148
|
}
|
|
3003
3149
|
try {
|
|
3004
|
-
const { execFileSync:
|
|
3005
|
-
envChecks["git"] =
|
|
3150
|
+
const { execFileSync: execFileSync4 } = await import("node:child_process");
|
|
3151
|
+
envChecks["git"] = execFileSync4("git", ["--version"], { encoding: "utf-8" }).trim().replace("git version ", "");
|
|
3006
3152
|
} catch {
|
|
3007
3153
|
envChecks["git"] = null;
|
|
3008
3154
|
}
|
|
@@ -3181,7 +3327,7 @@ var init_doctor = __esm({
|
|
|
3181
3327
|
|
|
3182
3328
|
// src/commands/courses.ts
|
|
3183
3329
|
import { Command as Command5 } from "commander";
|
|
3184
|
-
var
|
|
3330
|
+
var logger5, coursesCommand;
|
|
3185
3331
|
var init_courses2 = __esm({
|
|
3186
3332
|
"src/commands/courses.ts"() {
|
|
3187
3333
|
"use strict";
|
|
@@ -3190,12 +3336,12 @@ var init_courses2 = __esm({
|
|
|
3190
3336
|
init_http();
|
|
3191
3337
|
init_guards();
|
|
3192
3338
|
init_formatter();
|
|
3193
|
-
|
|
3339
|
+
logger5 = createLogger("cli:courses");
|
|
3194
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) => {
|
|
3195
3341
|
try {
|
|
3196
3342
|
const session = await requireSession();
|
|
3197
3343
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3198
|
-
const deps = { data, logger:
|
|
3344
|
+
const deps = { data, logger: logger5 };
|
|
3199
3345
|
let coursesToList;
|
|
3200
3346
|
if (opts.mine) {
|
|
3201
3347
|
coursesToList = await data.courses.listCreatorCourses({
|
|
@@ -3527,7 +3673,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3527
3673
|
});
|
|
3528
3674
|
}
|
|
3529
3675
|
} catch (err) {
|
|
3530
|
-
|
|
3676
|
+
logger6.warn("T0 fetch failed \u2014 rendering without persona", { err });
|
|
3531
3677
|
tutorPersona = null;
|
|
3532
3678
|
}
|
|
3533
3679
|
}
|
|
@@ -3551,7 +3697,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3551
3697
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3552
3698
|
});
|
|
3553
3699
|
} catch (err) {
|
|
3554
|
-
|
|
3700
|
+
logger6.warn("T1 fetch failed \u2014 rendering without brief", { err });
|
|
3555
3701
|
}
|
|
3556
3702
|
}
|
|
3557
3703
|
if (!studentBrief && options.collectT1Interactive) {
|
|
@@ -3571,7 +3717,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3571
3717
|
});
|
|
3572
3718
|
bootstrapped = "t1";
|
|
3573
3719
|
} catch (err) {
|
|
3574
|
-
|
|
3720
|
+
logger6.warn("T1 bootstrap failed", { err });
|
|
3575
3721
|
}
|
|
3576
3722
|
}
|
|
3577
3723
|
let enrollmentProfile = null;
|
|
@@ -3585,7 +3731,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3585
3731
|
enrollmentProfile = onboarding.learnerProfile;
|
|
3586
3732
|
}
|
|
3587
3733
|
} catch (err) {
|
|
3588
|
-
|
|
3734
|
+
logger6.warn("T2 fetch failed \u2014 rendering without enrollment profile", { err });
|
|
3589
3735
|
}
|
|
3590
3736
|
const content = renderCourseInstruction({
|
|
3591
3737
|
course: {
|
|
@@ -3609,7 +3755,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3609
3755
|
courseTitle: courseMeta.courseTitle
|
|
3610
3756
|
});
|
|
3611
3757
|
} catch (err) {
|
|
3612
|
-
|
|
3758
|
+
logger6.warn("Failed to write workspace marker", { err });
|
|
3613
3759
|
}
|
|
3614
3760
|
if (markerPath) {
|
|
3615
3761
|
try {
|
|
@@ -3619,7 +3765,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3619
3765
|
lastInitCourseId: input2.courseId
|
|
3620
3766
|
});
|
|
3621
3767
|
} catch (err) {
|
|
3622
|
-
|
|
3768
|
+
logger6.warn("Failed to update workspace state v2 fields", {
|
|
3623
3769
|
error: err instanceof Error ? err.message : String(err)
|
|
3624
3770
|
});
|
|
3625
3771
|
}
|
|
@@ -3634,7 +3780,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3634
3780
|
renderedInstruction: content
|
|
3635
3781
|
};
|
|
3636
3782
|
}
|
|
3637
|
-
var
|
|
3783
|
+
var logger6, defaultDeps2;
|
|
3638
3784
|
var init_instruction_pipeline = __esm({
|
|
3639
3785
|
"src/instruction-pipeline.ts"() {
|
|
3640
3786
|
"use strict";
|
|
@@ -3649,7 +3795,7 @@ var init_instruction_pipeline = __esm({
|
|
|
3649
3795
|
init_api3();
|
|
3650
3796
|
init_session_store();
|
|
3651
3797
|
init_instruction_template_v3();
|
|
3652
|
-
|
|
3798
|
+
logger6 = createLogger("cli:instruction-pipeline");
|
|
3653
3799
|
defaultDeps2 = {
|
|
3654
3800
|
fetchTutorPersona: fetchTutorPersonality,
|
|
3655
3801
|
fetchLearnerBrief,
|
|
@@ -3672,7 +3818,7 @@ var init_instruction_pipeline = __esm({
|
|
|
3672
3818
|
async function fetchCourseMetaViaHttp(input2) {
|
|
3673
3819
|
const { session, courseId, enrollmentId } = input2;
|
|
3674
3820
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3675
|
-
const coreDeps = { data, logger:
|
|
3821
|
+
const coreDeps = { data, logger: logger7 };
|
|
3676
3822
|
const detail = await selectCourse({ userId: session.userId, courseId }, coreDeps);
|
|
3677
3823
|
let currentModuleTitle;
|
|
3678
3824
|
let currentLessonTitle;
|
|
@@ -3681,7 +3827,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3681
3827
|
currentModuleTitle = progress3.currentModule?.title;
|
|
3682
3828
|
currentLessonTitle = progress3.currentLesson?.title;
|
|
3683
3829
|
} catch (err) {
|
|
3684
|
-
|
|
3830
|
+
logger7.debug("getProgress failed \u2014 falling back to basic course meta", {
|
|
3685
3831
|
error: err instanceof Error ? err.message : String(err)
|
|
3686
3832
|
});
|
|
3687
3833
|
}
|
|
@@ -3695,7 +3841,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3695
3841
|
courseLevel = match.level;
|
|
3696
3842
|
}
|
|
3697
3843
|
} catch (err) {
|
|
3698
|
-
|
|
3844
|
+
logger7.debug("listCourses failed \u2014 skipping tags/level", {
|
|
3699
3845
|
error: err instanceof Error ? err.message : String(err)
|
|
3700
3846
|
});
|
|
3701
3847
|
}
|
|
@@ -3715,7 +3861,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3715
3861
|
}
|
|
3716
3862
|
};
|
|
3717
3863
|
}
|
|
3718
|
-
async function writeFilesAdapter(cwd, courseMeta, content) {
|
|
3864
|
+
async function writeFilesAdapter(cwd, courseMeta, content, opts = {}) {
|
|
3719
3865
|
return writeInstructionFiles(
|
|
3720
3866
|
cwd,
|
|
3721
3867
|
{
|
|
@@ -3728,17 +3874,18 @@ async function writeFilesAdapter(cwd, courseMeta, content) {
|
|
|
3728
3874
|
currentLessonTitle: courseMeta.progress.currentLessonTitle,
|
|
3729
3875
|
courseDescription: courseMeta.courseDescription
|
|
3730
3876
|
},
|
|
3731
|
-
content
|
|
3877
|
+
content,
|
|
3878
|
+
{ allRuntimes: opts.allRuntimes }
|
|
3732
3879
|
);
|
|
3733
3880
|
}
|
|
3734
|
-
function buildPipelineDeps() {
|
|
3881
|
+
function buildPipelineDeps(opts = {}) {
|
|
3735
3882
|
return {
|
|
3736
3883
|
...defaultDeps2,
|
|
3737
3884
|
fetchCourseMeta: fetchCourseMetaViaHttp,
|
|
3738
|
-
writeFiles: writeFilesAdapter
|
|
3885
|
+
writeFiles: (cwd, courseMeta, content) => writeFilesAdapter(cwd, courseMeta, content, opts)
|
|
3739
3886
|
};
|
|
3740
3887
|
}
|
|
3741
|
-
var
|
|
3888
|
+
var logger7;
|
|
3742
3889
|
var init_pipeline_deps = __esm({
|
|
3743
3890
|
"src/commands/_shared/pipeline-deps.ts"() {
|
|
3744
3891
|
"use strict";
|
|
@@ -3747,14 +3894,14 @@ var init_pipeline_deps = __esm({
|
|
|
3747
3894
|
init_http();
|
|
3748
3895
|
init_instruction_pipeline();
|
|
3749
3896
|
init_instruction_files();
|
|
3750
|
-
|
|
3897
|
+
logger7 = createLogger("cli:pipeline-deps");
|
|
3751
3898
|
}
|
|
3752
3899
|
});
|
|
3753
3900
|
|
|
3754
3901
|
// src/commands/select.ts
|
|
3755
3902
|
import { Command as Command6 } from "commander";
|
|
3756
3903
|
import os7 from "node:os";
|
|
3757
|
-
var
|
|
3904
|
+
var logger8, selectCommand;
|
|
3758
3905
|
var init_select = __esm({
|
|
3759
3906
|
"src/commands/select.ts"() {
|
|
3760
3907
|
"use strict";
|
|
@@ -3764,17 +3911,18 @@ var init_select = __esm({
|
|
|
3764
3911
|
init_guards();
|
|
3765
3912
|
init_workspace_marker();
|
|
3766
3913
|
init_resolve();
|
|
3914
|
+
init_runtime_registry();
|
|
3767
3915
|
init_formatter();
|
|
3768
3916
|
init_errors();
|
|
3769
3917
|
init_status();
|
|
3770
3918
|
init_instruction_pipeline();
|
|
3771
3919
|
init_pipeline_deps();
|
|
3772
|
-
|
|
3920
|
+
logger8 = createLogger("cli:select");
|
|
3773
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) => {
|
|
3774
3922
|
try {
|
|
3775
3923
|
const session = await requireSession();
|
|
3776
3924
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3777
|
-
const deps = { data, logger:
|
|
3925
|
+
const deps = { data, logger: logger8 };
|
|
3778
3926
|
const courses3 = await listCourses({ userId: session.userId }, deps);
|
|
3779
3927
|
let courseId = course;
|
|
3780
3928
|
let enrollmentId = "";
|
|
@@ -3813,7 +3961,7 @@ var init_select = __esm({
|
|
|
3813
3961
|
{ cwd: process.cwd(), deps: buildPipelineDeps() }
|
|
3814
3962
|
);
|
|
3815
3963
|
} catch (err) {
|
|
3816
|
-
|
|
3964
|
+
logger8.warn("Failed to run instruction pipeline", {
|
|
3817
3965
|
error: err instanceof Error ? err.message : String(err)
|
|
3818
3966
|
});
|
|
3819
3967
|
}
|
|
@@ -3864,12 +4012,18 @@ var init_select = __esm({
|
|
|
3864
4012
|
if (pipelineResult && !pipelineResult.usedT1) {
|
|
3865
4013
|
lines.push(" (sem brief base \u2014 rode `tostudy init` para configurar)");
|
|
3866
4014
|
}
|
|
3867
|
-
lines.push(
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
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");
|
|
3873
4027
|
output(lines.join("\n"), { json: false });
|
|
3874
4028
|
}
|
|
3875
4029
|
} catch (err) {
|
|
@@ -3886,7 +4040,7 @@ var init_select = __esm({
|
|
|
3886
4040
|
|
|
3887
4041
|
// src/commands/progress.ts
|
|
3888
4042
|
import { Command as Command7 } from "commander";
|
|
3889
|
-
var
|
|
4043
|
+
var logger9, progressCommand;
|
|
3890
4044
|
var init_progress = __esm({
|
|
3891
4045
|
"src/commands/progress.ts"() {
|
|
3892
4046
|
"use strict";
|
|
@@ -3897,7 +4051,7 @@ var init_progress = __esm({
|
|
|
3897
4051
|
init_course_state();
|
|
3898
4052
|
init_formatter();
|
|
3899
4053
|
init_errors();
|
|
3900
|
-
|
|
4054
|
+
logger9 = createLogger("cli:progress");
|
|
3901
4055
|
progressCommand = new Command7("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
3902
4056
|
try {
|
|
3903
4057
|
const session = await requireSession();
|
|
@@ -3905,7 +4059,7 @@ var init_progress = __esm({
|
|
|
3905
4059
|
const driftWarning = await checkCourseDrift();
|
|
3906
4060
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
3907
4061
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3908
|
-
const deps = { data, logger:
|
|
4062
|
+
const deps = { data, logger: logger9 };
|
|
3909
4063
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
3910
4064
|
if (opts.json) {
|
|
3911
4065
|
output(progress3, { json: true });
|
|
@@ -14279,12 +14433,12 @@ var init_session2 = __esm({
|
|
|
14279
14433
|
init_tracing();
|
|
14280
14434
|
init_utils();
|
|
14281
14435
|
PostgresJsPreparedQuery = class extends PgPreparedQuery {
|
|
14282
|
-
constructor(client, queryString, params,
|
|
14436
|
+
constructor(client, queryString, params, logger35, cache, queryMetadata, cacheConfig, fields, _isResponseInArrayMode, customResultMapper) {
|
|
14283
14437
|
super({ sql: queryString, params }, cache, queryMetadata, cacheConfig);
|
|
14284
14438
|
this.client = client;
|
|
14285
14439
|
this.queryString = queryString;
|
|
14286
14440
|
this.params = params;
|
|
14287
|
-
this.logger =
|
|
14441
|
+
this.logger = logger35;
|
|
14288
14442
|
this.fields = fields;
|
|
14289
14443
|
this._isResponseInArrayMode = _isResponseInArrayMode;
|
|
14290
14444
|
this.customResultMapper = customResultMapper;
|
|
@@ -14425,11 +14579,11 @@ function construct(client, config2 = {}) {
|
|
|
14425
14579
|
client.options.serializers["114"] = transparentParser;
|
|
14426
14580
|
client.options.serializers["3802"] = transparentParser;
|
|
14427
14581
|
const dialect = new PgDialect({ casing: config2.casing });
|
|
14428
|
-
let
|
|
14582
|
+
let logger35;
|
|
14429
14583
|
if (config2.logger === true) {
|
|
14430
|
-
|
|
14584
|
+
logger35 = new DefaultLogger();
|
|
14431
14585
|
} else if (config2.logger !== false) {
|
|
14432
|
-
|
|
14586
|
+
logger35 = config2.logger;
|
|
14433
14587
|
}
|
|
14434
14588
|
let schema;
|
|
14435
14589
|
if (config2.schema) {
|
|
@@ -14443,7 +14597,7 @@ function construct(client, config2 = {}) {
|
|
|
14443
14597
|
tableNamesMap: tablesConfig.tableNamesMap
|
|
14444
14598
|
};
|
|
14445
14599
|
}
|
|
14446
|
-
const session = new PostgresJsSession(client, dialect, schema, { logger:
|
|
14600
|
+
const session = new PostgresJsSession(client, dialect, schema, { logger: logger35, cache: config2.cache });
|
|
14447
14601
|
const db2 = new PostgresJsDatabase(dialect, session, schema);
|
|
14448
14602
|
db2.$client = client;
|
|
14449
14603
|
db2.$cache = config2.cache;
|
|
@@ -29169,7 +29323,7 @@ var init_user_preferences = __esm({
|
|
|
29169
29323
|
});
|
|
29170
29324
|
|
|
29171
29325
|
// ../../packages/database/src/schema/mcp.ts
|
|
29172
|
-
var mcpSessions, syncLogs
|
|
29326
|
+
var mcpSessions, syncLogs;
|
|
29173
29327
|
var init_mcp = __esm({
|
|
29174
29328
|
"../../packages/database/src/schema/mcp.ts"() {
|
|
29175
29329
|
"use strict";
|
|
@@ -29232,11 +29386,6 @@ var init_mcp = __esm({
|
|
|
29232
29386
|
syncedAtIdx: index("idx_sync_logs_synced_at").on(table.syncedAt)
|
|
29233
29387
|
})
|
|
29234
29388
|
);
|
|
29235
|
-
platformConfig = pgTable("platform_config", {
|
|
29236
|
-
key: varchar("key", { length: 50 }).primaryKey(),
|
|
29237
|
-
value: text("value").notNull(),
|
|
29238
|
-
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
29239
|
-
});
|
|
29240
29389
|
}
|
|
29241
29390
|
});
|
|
29242
29391
|
|
|
@@ -29570,6 +29719,13 @@ var init_tutor_feedback = __esm({
|
|
|
29570
29719
|
}
|
|
29571
29720
|
});
|
|
29572
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
|
+
|
|
29573
29729
|
// ../../packages/types/src/errors.ts
|
|
29574
29730
|
var init_errors6 = __esm({
|
|
29575
29731
|
"../../packages/types/src/errors.ts"() {
|
|
@@ -29601,7 +29757,8 @@ var init_credit_payment_enums = __esm({
|
|
|
29601
29757
|
// course_sale_credit (legacy Stripe 20/85) so reconciliation/clawback never
|
|
29602
29758
|
// conflate the two funding models.
|
|
29603
29759
|
"course_enrollment_debit",
|
|
29604
|
-
"course_enrollment_credit"
|
|
29760
|
+
"course_enrollment_credit",
|
|
29761
|
+
"referral_bonus"
|
|
29605
29762
|
];
|
|
29606
29763
|
CREDIT_SUBSCRIPTION_STATUS_VALUES = [
|
|
29607
29764
|
"active",
|
|
@@ -29621,6 +29778,13 @@ var init_credit_payment_enums = __esm({
|
|
|
29621
29778
|
}
|
|
29622
29779
|
});
|
|
29623
29780
|
|
|
29781
|
+
// ../../packages/types/src/referral.ts
|
|
29782
|
+
var init_referral = __esm({
|
|
29783
|
+
"../../packages/types/src/referral.ts"() {
|
|
29784
|
+
"use strict";
|
|
29785
|
+
}
|
|
29786
|
+
});
|
|
29787
|
+
|
|
29624
29788
|
// ../../packages/types/src/index.ts
|
|
29625
29789
|
var init_src2 = __esm({
|
|
29626
29790
|
"../../packages/types/src/index.ts"() {
|
|
@@ -29634,8 +29798,10 @@ var init_src2 = __esm({
|
|
|
29634
29798
|
init_exercise_type();
|
|
29635
29799
|
init_lesson_contract();
|
|
29636
29800
|
init_tutor_feedback();
|
|
29801
|
+
init_lesson_review();
|
|
29637
29802
|
init_errors6();
|
|
29638
29803
|
init_credit_payment_enums();
|
|
29804
|
+
init_referral();
|
|
29639
29805
|
}
|
|
29640
29806
|
});
|
|
29641
29807
|
|
|
@@ -30018,7 +30184,7 @@ var init_llm_analytics = __esm({
|
|
|
30018
30184
|
// Operation type
|
|
30019
30185
|
operationType: varchar("operation_type", { length: 50 }).notNull(),
|
|
30020
30186
|
// Provider (references llm_provider enum from llm-pricing.ts)
|
|
30021
|
-
provider: llmProviderEnum("provider").notNull().default("
|
|
30187
|
+
provider: llmProviderEnum("provider").notNull().default("other"),
|
|
30022
30188
|
// Tracing
|
|
30023
30189
|
correlationId: varchar("correlation_id", { length: 64 }),
|
|
30024
30190
|
// Relationships
|
|
@@ -30038,6 +30204,11 @@ var init_llm_analytics = __esm({
|
|
|
30038
30204
|
responseTokens: integer("response_tokens"),
|
|
30039
30205
|
// Cost & Revenue
|
|
30040
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 }),
|
|
30041
30212
|
revenueUsd: decimal("revenue_usd", { precision: 10, scale: 6 }).default("0"),
|
|
30042
30213
|
// Cache metrics (prompt caching)
|
|
30043
30214
|
cacheCreationTokens: integer("cache_creation_tokens").default(0),
|
|
@@ -30064,6 +30235,12 @@ var init_llm_analytics = __esm({
|
|
|
30064
30235
|
"llm_interactions_status_check",
|
|
30065
30236
|
sql`${table.status} IN ('pending', 'success', 'error', 'timeout', 'abandoned')`
|
|
30066
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
|
+
),
|
|
30067
30244
|
creatorIdx: index("idx_llm_interactions_creator").on(table.creatorId, table.createdAt),
|
|
30068
30245
|
operationIdx: index("idx_llm_interactions_operation").on(table.operationType, table.createdAt),
|
|
30069
30246
|
correlationIdx: index("idx_llm_interactions_correlation").on(table.correlationId),
|
|
@@ -30150,7 +30327,9 @@ var init_credit_wallets = __esm({
|
|
|
30150
30327
|
// Credits-first (WS3/WS4): student debit (-), creator full-price credit (+).
|
|
30151
30328
|
course_enrollment_debit: "negative",
|
|
30152
30329
|
course_enrollment_credit: "positive",
|
|
30153
|
-
adjustment: "either"
|
|
30330
|
+
adjustment: "either",
|
|
30331
|
+
// Referral program (spec 2026-07-17): both-sides fixed grant on first purchase.
|
|
30332
|
+
referral_bonus: "positive"
|
|
30154
30333
|
};
|
|
30155
30334
|
WITHDRAWABLE_LEDGER_TYPES = [
|
|
30156
30335
|
"course_sale_credit",
|
|
@@ -30196,6 +30375,7 @@ var init_credit_wallets = __esm({
|
|
|
30196
30375
|
"subscription",
|
|
30197
30376
|
"package",
|
|
30198
30377
|
"withdrawal",
|
|
30378
|
+
"referral",
|
|
30199
30379
|
"backfill",
|
|
30200
30380
|
"credit_transaction_migration"
|
|
30201
30381
|
];
|
|
@@ -30250,6 +30430,12 @@ var init_credit_wallets = __esm({
|
|
|
30250
30430
|
// the PK). Raw `sql` literal (not eq()) to dodge the drizzle-kit `$N`
|
|
30251
30431
|
// placeholder DDL bug — see packages/database/AGENTS.md.
|
|
30252
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'`),
|
|
30253
30439
|
// Idempotency guard for the AI-consumption reconciliation sweep (CHORE-credit-recon).
|
|
30254
30440
|
// The sweep must not double-charge a debit the inline path already committed;
|
|
30255
30441
|
// this index makes the DB the final arbiter — a second ai_consumption insert
|
|
@@ -30259,23 +30445,34 @@ var init_credit_wallets = __esm({
|
|
|
30259
30445
|
// Raw `sql` literal (not eq()) to dodge the drizzle-kit `$N` placeholder DDL
|
|
30260
30446
|
// bug (packages/database/AGENTS.md).
|
|
30261
30447
|
aiConsumptionInteractionUniq: uniqueIndex("cwt_ai_consumption_interaction_uniq").on(table.interactionId).where(sql`${table.type} = 'ai_consumption' AND ${table.interactionId} IS NOT NULL`),
|
|
30262
|
-
// Credits-first (
|
|
30263
|
-
//
|
|
30264
|
-
//
|
|
30265
|
-
//
|
|
30266
|
-
//
|
|
30267
|
-
//
|
|
30268
|
-
//
|
|
30269
|
-
//
|
|
30270
|
-
//
|
|
30271
|
-
//
|
|
30272
|
-
//
|
|
30273
|
-
//
|
|
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
|
+
),
|
|
30274
30471
|
referenceTypeCheck: check(
|
|
30275
30472
|
"cwt_reference_type_check",
|
|
30276
30473
|
sql`${table.referenceType} IS NULL OR ${table.referenceType} IN (
|
|
30277
30474
|
'ai_operation', 'enrollment', 'booking',
|
|
30278
|
-
'subscription', 'package', 'withdrawal',
|
|
30475
|
+
'subscription', 'package', 'withdrawal', 'referral',
|
|
30279
30476
|
'backfill', 'credit_transaction_migration'
|
|
30280
30477
|
)`
|
|
30281
30478
|
)
|
|
@@ -30374,7 +30571,13 @@ var init_credit_packages = __esm({
|
|
|
30374
30571
|
(table) => ({
|
|
30375
30572
|
userIdx: index("cs_user_idx").on(table.userId),
|
|
30376
30573
|
stripeSubIdx: index("cs_stripe_sub_idx").on(table.stripeSubscriptionId),
|
|
30377
|
-
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'`)
|
|
30378
30581
|
})
|
|
30379
30582
|
);
|
|
30380
30583
|
}
|
|
@@ -31037,7 +31240,7 @@ var init_enrollment_channel_changes = __esm({
|
|
|
31037
31240
|
});
|
|
31038
31241
|
|
|
31039
31242
|
// ../../packages/database/migrations/schema.ts
|
|
31040
|
-
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;
|
|
31041
31244
|
var init_schema2 = __esm({
|
|
31042
31245
|
"../../packages/database/migrations/schema.ts"() {
|
|
31043
31246
|
"use strict";
|
|
@@ -31500,7 +31703,7 @@ var init_schema2 = __esm({
|
|
|
31500
31703
|
}).onDelete("cascade")
|
|
31501
31704
|
]
|
|
31502
31705
|
);
|
|
31503
|
-
|
|
31706
|
+
platformConfig = pgTable("platform_config", {
|
|
31504
31707
|
key: varchar({ length: 50 }).primaryKey().notNull(),
|
|
31505
31708
|
value: text().notNull(),
|
|
31506
31709
|
updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().notNull()
|
|
@@ -35896,13 +36099,17 @@ var init_mentorship_credits = __esm({
|
|
|
35896
36099
|
// Package lookup
|
|
35897
36100
|
packageIdIdx: index("mentorship_credits_package_id_idx").on(table.packageId),
|
|
35898
36101
|
// Stripe payment intent lookup (for webhook idempotency)
|
|
35899
|
-
|
|
35900
|
-
table.stripePaymentIntentId
|
|
35901
|
-
),
|
|
36102
|
+
stripePaymentIntentIdUnique: uniqueIndex("mentorship_credits_stripe_payment_intent_unique").on(table.stripePaymentIntentId).where(sql`${table.stripePaymentIntentId} IS NOT NULL`),
|
|
35902
36103
|
// ORDER BY purchasedAt DESC (credit transaction history)
|
|
35903
36104
|
purchasedAtIdx: index("mentorship_credits_purchased_at_idx").on(table.purchasedAt),
|
|
35904
36105
|
// FEAT-1288: refund revoke looks up course-granted credits by enrollment
|
|
35905
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`),
|
|
35906
36113
|
// FEAT-1288: each origin carries its tracing FK — package rows keep a
|
|
35907
36114
|
// package_id, course-purchase rows keep an enrollment_id.
|
|
35908
36115
|
originConsistencyCheck: check(
|
|
@@ -35996,6 +36203,7 @@ var init_mentorship_transactions = __esm({
|
|
|
35996
36203
|
"../../packages/database/src/schema/mentorship-transactions.ts"() {
|
|
35997
36204
|
"use strict";
|
|
35998
36205
|
init_pg_core();
|
|
36206
|
+
init_drizzle_orm();
|
|
35999
36207
|
init_users();
|
|
36000
36208
|
init_mentorship_sessions();
|
|
36001
36209
|
init_mentorship_packages();
|
|
@@ -36096,9 +36304,9 @@ var init_mentorship_transactions = __esm({
|
|
|
36096
36304
|
studentIdIdx: index("mentorship_transactions_student_id_idx").on(table.studentId),
|
|
36097
36305
|
mentorIdIdx: index("mentorship_transactions_mentor_id_idx").on(table.mentorId),
|
|
36098
36306
|
statusIdx: index("mentorship_transactions_status_idx").on(table.status),
|
|
36099
|
-
|
|
36100
|
-
|
|
36101
|
-
),
|
|
36307
|
+
stripePaymentIntentIdUnique: uniqueIndex(
|
|
36308
|
+
"mentorship_transactions_stripe_payment_intent_id_unique"
|
|
36309
|
+
).on(table.stripePaymentIntentId).where(sql`${table.stripePaymentIntentId} IS NOT NULL`),
|
|
36102
36310
|
createdAtIdx: index("mentorship_transactions_created_at_idx").on(table.createdAt),
|
|
36103
36311
|
// Story 19.3: Additional indexes for split and aggregation
|
|
36104
36312
|
typeIdx: index("mentorship_transactions_type_idx").on(table.transactionType),
|
|
@@ -37526,6 +37734,7 @@ var init_transactions = __esm({
|
|
|
37526
37734
|
"../../packages/database/src/schema/transactions.ts"() {
|
|
37527
37735
|
"use strict";
|
|
37528
37736
|
init_pg_core();
|
|
37737
|
+
init_drizzle_orm();
|
|
37529
37738
|
init_courses3();
|
|
37530
37739
|
init_users();
|
|
37531
37740
|
init_enrollments();
|
|
@@ -37534,9 +37743,13 @@ var init_transactions = __esm({
|
|
|
37534
37743
|
{
|
|
37535
37744
|
id: uuid("id").defaultRandom().primaryKey(),
|
|
37536
37745
|
// Stripe references
|
|
37537
|
-
stripePaymentIntentId: varchar("stripe_payment_intent_id", { length: 255 }).
|
|
37746
|
+
stripePaymentIntentId: varchar("stripe_payment_intent_id", { length: 255 }).unique(),
|
|
37538
37747
|
stripeTransferId: varchar("stripe_transfer_id", { length: 255 }),
|
|
37539
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 }),
|
|
37540
37753
|
// Foreign keys
|
|
37541
37754
|
courseId: uuid("course_id").notNull().references(() => courses.id, { onDelete: "restrict" }),
|
|
37542
37755
|
creatorId: uuid("creator_id").notNull().references(() => users.id, { onDelete: "restrict" }),
|
|
@@ -37608,6 +37821,56 @@ var init_transactions = __esm({
|
|
|
37608
37821
|
table.studentId,
|
|
37609
37822
|
table.status,
|
|
37610
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')`
|
|
37611
37874
|
)
|
|
37612
37875
|
})
|
|
37613
37876
|
);
|
|
@@ -38527,140 +38790,6 @@ var init_study_index = __esm({
|
|
|
38527
38790
|
}
|
|
38528
38791
|
});
|
|
38529
38792
|
|
|
38530
|
-
// ../../packages/database/src/schema/platform-settings.ts
|
|
38531
|
-
function parseSettingValue(value, valueType) {
|
|
38532
|
-
switch (valueType) {
|
|
38533
|
-
case "boolean":
|
|
38534
|
-
return value === "true";
|
|
38535
|
-
case "number":
|
|
38536
|
-
return Number(value);
|
|
38537
|
-
case "json":
|
|
38538
|
-
try {
|
|
38539
|
-
return JSON.parse(value);
|
|
38540
|
-
} catch {
|
|
38541
|
-
return null;
|
|
38542
|
-
}
|
|
38543
|
-
default:
|
|
38544
|
-
return value;
|
|
38545
|
-
}
|
|
38546
|
-
}
|
|
38547
|
-
function stringifySettingValue(value, valueType) {
|
|
38548
|
-
switch (valueType) {
|
|
38549
|
-
case "boolean":
|
|
38550
|
-
return value ? "true" : "false";
|
|
38551
|
-
case "number":
|
|
38552
|
-
return String(value);
|
|
38553
|
-
case "json":
|
|
38554
|
-
return JSON.stringify(value);
|
|
38555
|
-
default:
|
|
38556
|
-
return String(value);
|
|
38557
|
-
}
|
|
38558
|
-
}
|
|
38559
|
-
var settingValueTypes, settingCategories, platformSettings2, insertPlatformSettingSchema, selectPlatformSettingSchema, settingKeys;
|
|
38560
|
-
var init_platform_settings = __esm({
|
|
38561
|
-
"../../packages/database/src/schema/platform-settings.ts"() {
|
|
38562
|
-
"use strict";
|
|
38563
|
-
init_pg_core();
|
|
38564
|
-
init_zod();
|
|
38565
|
-
settingValueTypes = ["string", "boolean", "number", "json"];
|
|
38566
|
-
settingCategories = [
|
|
38567
|
-
"platform",
|
|
38568
|
-
"notifications",
|
|
38569
|
-
"security",
|
|
38570
|
-
"email",
|
|
38571
|
-
"financial"
|
|
38572
|
-
];
|
|
38573
|
-
platformSettings2 = pgTable(
|
|
38574
|
-
"platform_settings",
|
|
38575
|
-
{
|
|
38576
|
-
key: varchar("key", { length: 100 }).primaryKey(),
|
|
38577
|
-
value: text("value").notNull(),
|
|
38578
|
-
valueType: varchar("value_type", { length: 20 }).notNull().default("string"),
|
|
38579
|
-
category: varchar("category", { length: 50 }).notNull().default("general"),
|
|
38580
|
-
description: text("description"),
|
|
38581
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
|
|
38582
|
-
updatedBy: varchar("updated_by", { length: 255 })
|
|
38583
|
-
},
|
|
38584
|
-
(table) => [index("idx_platform_settings_category").on(table.category)]
|
|
38585
|
-
);
|
|
38586
|
-
insertPlatformSettingSchema = external_exports.object({
|
|
38587
|
-
key: external_exports.string().min(1).max(100),
|
|
38588
|
-
value: external_exports.string(),
|
|
38589
|
-
valueType: external_exports.enum(settingValueTypes).default("string"),
|
|
38590
|
-
category: external_exports.enum(settingCategories).default("platform"),
|
|
38591
|
-
description: external_exports.string().nullable().optional(),
|
|
38592
|
-
updatedBy: external_exports.string().nullable().optional()
|
|
38593
|
-
});
|
|
38594
|
-
selectPlatformSettingSchema = external_exports.object({
|
|
38595
|
-
key: external_exports.string(),
|
|
38596
|
-
value: external_exports.string(),
|
|
38597
|
-
valueType: external_exports.string(),
|
|
38598
|
-
category: external_exports.string(),
|
|
38599
|
-
description: external_exports.string().nullable(),
|
|
38600
|
-
updatedAt: external_exports.date().nullable(),
|
|
38601
|
-
updatedBy: external_exports.string().nullable()
|
|
38602
|
-
});
|
|
38603
|
-
settingKeys = {
|
|
38604
|
-
// Platform
|
|
38605
|
-
platformName: "platform_name",
|
|
38606
|
-
platformUrl: "platform_url",
|
|
38607
|
-
platformLogoUrl: "platform_logo_url",
|
|
38608
|
-
platformDescription: "platform_description",
|
|
38609
|
-
maintenanceMode: "maintenance_mode",
|
|
38610
|
-
// Notifications
|
|
38611
|
-
emailWelcome: "email_welcome",
|
|
38612
|
-
emailCourseApproved: "email_course_approved",
|
|
38613
|
-
emailNewEnrollment: "email_new_enrollment",
|
|
38614
|
-
adminSystemAlerts: "admin_system_alerts",
|
|
38615
|
-
// Security
|
|
38616
|
-
mfaRequiredAdmins: "mfa_required_admins",
|
|
38617
|
-
mfaRequiredCreators: "mfa_required_creators",
|
|
38618
|
-
sessionTimeoutMinutes: "session_timeout_minutes",
|
|
38619
|
-
maxLoginAttempts: "max_login_attempts",
|
|
38620
|
-
// Email
|
|
38621
|
-
emailFrom: "email_from",
|
|
38622
|
-
emailFromName: "email_from_name"
|
|
38623
|
-
};
|
|
38624
|
-
}
|
|
38625
|
-
});
|
|
38626
|
-
|
|
38627
|
-
// ../../packages/database/src/schema/admin-settings-audit.ts
|
|
38628
|
-
var adminSettingsAudit, adminSettingsAuditRelations;
|
|
38629
|
-
var init_admin_settings_audit = __esm({
|
|
38630
|
-
"../../packages/database/src/schema/admin-settings-audit.ts"() {
|
|
38631
|
-
"use strict";
|
|
38632
|
-
init_pg_core();
|
|
38633
|
-
init_drizzle_orm();
|
|
38634
|
-
init_users();
|
|
38635
|
-
adminSettingsAudit = pgTable(
|
|
38636
|
-
"admin_settings_audit",
|
|
38637
|
-
{
|
|
38638
|
-
id: uuid("id").defaultRandom().primaryKey(),
|
|
38639
|
-
// What changed
|
|
38640
|
-
settingKey: varchar("setting_key", { length: 100 }).notNull(),
|
|
38641
|
-
previousValue: jsonb("previous_value"),
|
|
38642
|
-
// nullable for new settings
|
|
38643
|
-
newValue: jsonb("new_value").notNull(),
|
|
38644
|
-
// Who changed it
|
|
38645
|
-
adminId: uuid("admin_id").references(() => users.id, { onDelete: "set null" }),
|
|
38646
|
-
// When
|
|
38647
|
-
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
38648
|
-
},
|
|
38649
|
-
(table) => ({
|
|
38650
|
-
settingKeyIdx: index("admin_settings_audit_setting_key_idx").on(table.settingKey),
|
|
38651
|
-
adminIdIdx: index("admin_settings_audit_admin_id_idx").on(table.adminId),
|
|
38652
|
-
createdAtIdx: index("admin_settings_audit_created_at_idx").on(table.createdAt)
|
|
38653
|
-
})
|
|
38654
|
-
);
|
|
38655
|
-
adminSettingsAuditRelations = relations(adminSettingsAudit, ({ one }) => ({
|
|
38656
|
-
admin: one(users, {
|
|
38657
|
-
fields: [adminSettingsAudit.adminId],
|
|
38658
|
-
references: [users.id]
|
|
38659
|
-
})
|
|
38660
|
-
}));
|
|
38661
|
-
}
|
|
38662
|
-
});
|
|
38663
|
-
|
|
38664
38793
|
// ../../packages/database/src/schema/admin-activity-feed.ts
|
|
38665
38794
|
var adminActivityFeed, adminActivityFeedRelations;
|
|
38666
38795
|
var init_admin_activity_feed = __esm({
|
|
@@ -39870,26 +39999,19 @@ var init_system_config = __esm({
|
|
|
39870
39999
|
}));
|
|
39871
40000
|
configKeys = {
|
|
39872
40001
|
// AI - Generation
|
|
39873
|
-
|
|
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.
|
|
39874
40004
|
"ai.generation.max_tokens": "ai.generation.max_tokens",
|
|
39875
40005
|
"ai.generation.temperature": "ai.generation.temperature",
|
|
39876
40006
|
// AI - Chat
|
|
39877
|
-
"ai.chat.model": "ai.chat.model",
|
|
39878
40007
|
"ai.chat.max_tokens": "ai.chat.max_tokens",
|
|
39879
40008
|
"ai.chat.temperature": "ai.chat.temperature",
|
|
39880
40009
|
// AI - Study
|
|
39881
|
-
"ai.study.chat_model": "ai.study.chat_model",
|
|
39882
|
-
"ai.study.hint_model": "ai.study.hint_model",
|
|
39883
40010
|
"ai.study.max_tokens": "ai.study.max_tokens",
|
|
39884
40011
|
"ai.study.temperature": "ai.study.temperature",
|
|
39885
|
-
// AI - Costs
|
|
40012
|
+
// AI - Costs (GH #947: cache_optimization_enabled and ai.context.* purged;
|
|
40013
|
+
// GH #974: requests_per_minute purged — reader never mounted)
|
|
39886
40014
|
"ai.costs.daily_limit_usd": "ai.costs.daily_limit_usd",
|
|
39887
|
-
"ai.costs.requests_per_minute": "ai.costs.requests_per_minute",
|
|
39888
|
-
"ai.costs.cache_optimization_enabled": "ai.costs.cache_optimization_enabled",
|
|
39889
|
-
// AI - Context Window Management
|
|
39890
|
-
"ai.context.window_size": "ai.context.window_size",
|
|
39891
|
-
"ai.context.output_reserve": "ai.context.output_reserve",
|
|
39892
|
-
"ai.context.compression_threshold": "ai.context.compression_threshold",
|
|
39893
40015
|
// Business - Pricing
|
|
39894
40016
|
"business.pricing.min_course_price_brl": "business.pricing.min_course_price_brl",
|
|
39895
40017
|
"business.pricing.course_mentoria_creator_share": "business.pricing.course_mentoria_creator_share",
|
|
@@ -39906,6 +40028,8 @@ var init_system_config = __esm({
|
|
|
39906
40028
|
"business.monitoring.prompt_caching_discount": "business.monitoring.prompt_caching_discount",
|
|
39907
40029
|
"business.monitoring.llm_cost_warning_usd": "business.monitoring.llm_cost_warning_usd",
|
|
39908
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",
|
|
39909
40033
|
// Business - Limits
|
|
39910
40034
|
"business.limits.max_courses_per_creator": "business.limits.max_courses_per_creator",
|
|
39911
40035
|
"business.limits.max_modules_per_course": "business.limits.max_modules_per_course",
|
|
@@ -39918,21 +40042,11 @@ var init_system_config = __esm({
|
|
|
39918
40042
|
"feature.community_enabled": "feature.community_enabled",
|
|
39919
40043
|
"feature.certificates_enabled": "feature.certificates_enabled",
|
|
39920
40044
|
"feature.maintenance_mode": "feature.maintenance_mode",
|
|
39921
|
-
"feature.new_user_registration": "feature.new_user_registration",
|
|
39922
40045
|
"feature.require_creator_mfa": "feature.require_creator_mfa",
|
|
39923
40046
|
"feature.require_admin_mfa": "feature.require_admin_mfa",
|
|
39924
|
-
|
|
39925
|
-
|
|
39926
|
-
// Platform Identity
|
|
39927
|
-
"platform.identity.name": "platform.identity.name",
|
|
39928
|
-
"platform.identity.url": "platform.identity.url",
|
|
39929
|
-
"platform.identity.logo_url": "platform.identity.logo_url",
|
|
39930
|
-
"platform.identity.description": "platform.identity.description",
|
|
40047
|
+
// GH #947: feature.security.*, platform.identity.* and the four
|
|
40048
|
+
// notification.email.* toggles purged — zero functional readers.
|
|
39931
40049
|
// Notification Settings
|
|
39932
|
-
"notification.email.welcome_enabled": "notification.email.welcome_enabled",
|
|
39933
|
-
"notification.email.course_approved_enabled": "notification.email.course_approved_enabled",
|
|
39934
|
-
"notification.email.new_enrollment_enabled": "notification.email.new_enrollment_enabled",
|
|
39935
|
-
"notification.email.admin_system_alerts": "notification.email.admin_system_alerts",
|
|
39936
40050
|
"notification.sender.from_address": "notification.sender.from_address",
|
|
39937
40051
|
"notification.sender.from_name": "notification.sender.from_name"
|
|
39938
40052
|
};
|
|
@@ -41203,7 +41317,6 @@ var init_relations_auth = __esm({
|
|
|
41203
41317
|
init_user_regional_settings();
|
|
41204
41318
|
init_users();
|
|
41205
41319
|
init_validation_attempts();
|
|
41206
|
-
init_admin_settings_audit();
|
|
41207
41320
|
init_brainstormings();
|
|
41208
41321
|
init_course_review_snapshots();
|
|
41209
41322
|
init_learning_paths();
|
|
@@ -41261,7 +41374,6 @@ var init_relations_auth = __esm({
|
|
|
41261
41374
|
dailyGoal: one(dailyGoals2),
|
|
41262
41375
|
dailyGoalProgress: many(dailyGoalProgress2),
|
|
41263
41376
|
regionalSettings: one(userRegionalSettings),
|
|
41264
|
-
adminSettingsAuditLogs: many(adminSettingsAudit),
|
|
41265
41377
|
creatorAuditLogs: many(creatorAuditLog),
|
|
41266
41378
|
lessonRefinements: many(lessonRefinements),
|
|
41267
41379
|
courseReviewSnapshots: many(courseReviewSnapshots),
|
|
@@ -43046,6 +43158,77 @@ var init_idempotency = __esm({
|
|
|
43046
43158
|
}
|
|
43047
43159
|
});
|
|
43048
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
|
+
|
|
43049
43232
|
// ../../packages/database/src/schema/user-deletions.ts
|
|
43050
43233
|
var userDeletionStatusEnum, userDeletions;
|
|
43051
43234
|
var init_user_deletions = __esm({
|
|
@@ -43249,6 +43432,55 @@ var init_subscription_redemptions = __esm({
|
|
|
43249
43432
|
}
|
|
43250
43433
|
});
|
|
43251
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
|
+
|
|
43252
43484
|
// ../../packages/database/src/schema/index.ts
|
|
43253
43485
|
var schema_exports = {};
|
|
43254
43486
|
__export(schema_exports, {
|
|
@@ -43264,6 +43496,8 @@ __export(schema_exports, {
|
|
|
43264
43496
|
PACKAGE_MINIMUM_PRICES: () => PACKAGE_MINIMUM_PRICES,
|
|
43265
43497
|
PACKAGE_SESSION_OPTIONS: () => PACKAGE_SESSION_OPTIONS,
|
|
43266
43498
|
PACKAGE_VALIDITY_OPTIONS: () => PACKAGE_VALIDITY_OPTIONS,
|
|
43499
|
+
PIX_CHARGE_PURPOSES: () => PIX_CHARGE_PURPOSES,
|
|
43500
|
+
PIX_CHARGE_STATUSES: () => PIX_CHARGE_STATUSES,
|
|
43267
43501
|
REVIEW_TAGS: () => REVIEW_TAGS,
|
|
43268
43502
|
SUGGESTED_DISCOUNTS: () => SUGGESTED_DISCOUNTS,
|
|
43269
43503
|
V3_CANCEL_REASON_TTL_SECONDS: () => V3_CANCEL_REASON_TTL_SECONDS,
|
|
@@ -43273,8 +43507,6 @@ __export(schema_exports, {
|
|
|
43273
43507
|
actionTypeEnum: () => actionTypeEnum,
|
|
43274
43508
|
adminActivityFeed: () => adminActivityFeed,
|
|
43275
43509
|
adminActivityFeedRelations: () => adminActivityFeedRelations,
|
|
43276
|
-
adminSettingsAudit: () => adminSettingsAudit,
|
|
43277
|
-
adminSettingsAuditRelations: () => adminSettingsAuditRelations,
|
|
43278
43510
|
announcementTypes: () => announcementTypes,
|
|
43279
43511
|
announcements: () => announcements,
|
|
43280
43512
|
applicableToEnum: () => applicableToEnum,
|
|
@@ -43441,7 +43673,6 @@ __export(schema_exports, {
|
|
|
43441
43673
|
insertCourseMentoriaOfferSchema: () => insertCourseMentoriaOfferSchema,
|
|
43442
43674
|
insertMentorshipCreditSchema: () => insertMentorshipCreditSchema,
|
|
43443
43675
|
insertMentorshipPackageSchema: () => insertMentorshipPackageSchema,
|
|
43444
|
-
insertPlatformSettingSchema: () => insertPlatformSettingSchema,
|
|
43445
43676
|
isAmountSignValid: () => isAmountSignValid,
|
|
43446
43677
|
isCreditUsable: () => isCreditUsable,
|
|
43447
43678
|
isWithdrawableLedgerType: () => isWithdrawableLedgerType,
|
|
@@ -43529,9 +43760,10 @@ __export(schema_exports, {
|
|
|
43529
43760
|
notificationsRelations: () => notificationsRelations2,
|
|
43530
43761
|
onboardingAnalytics: () => onboardingAnalytics2,
|
|
43531
43762
|
onboardingAnalyticsRelations: () => onboardingAnalyticsRelations2,
|
|
43763
|
+
operationBillingRates: () => operationBillingRates,
|
|
43764
|
+
operationBillingRatesHistory: () => operationBillingRatesHistory,
|
|
43532
43765
|
optimizerRoleEnum: () => optimizerRoleEnum,
|
|
43533
43766
|
parisAuthorizedCreators: () => parisAuthorizedCreators,
|
|
43534
|
-
parseSettingValue: () => parseSettingValue,
|
|
43535
43767
|
participantStatusEnum: () => participantStatusEnum,
|
|
43536
43768
|
pathCourses: () => pathCourses2,
|
|
43537
43769
|
pathCoursesRelations: () => pathCoursesRelations2,
|
|
@@ -43545,9 +43777,8 @@ __export(schema_exports, {
|
|
|
43545
43777
|
payoutWithdrawalTransitions: () => payoutWithdrawalTransitions,
|
|
43546
43778
|
payoutWithdrawals: () => payoutWithdrawals,
|
|
43547
43779
|
pgBackendIdempotencyKeys: () => pgBackendIdempotencyKeys,
|
|
43780
|
+
pixCharges: () => pixCharges,
|
|
43548
43781
|
pixKeyTypeEnum: () => pixKeyTypeEnum,
|
|
43549
|
-
platformConfig: () => platformConfig,
|
|
43550
|
-
platformSettings: () => platformSettings2,
|
|
43551
43782
|
playgroundEvalScores: () => playgroundEvalScores,
|
|
43552
43783
|
playgroundEvalScoresRelations: () => playgroundEvalScoresRelations,
|
|
43553
43784
|
playgroundEvaluations: () => playgroundEvaluations,
|
|
@@ -43591,6 +43822,8 @@ __export(schema_exports, {
|
|
|
43591
43822
|
pushTokens: () => pushTokens,
|
|
43592
43823
|
pushTokensRelations: () => pushTokensRelations,
|
|
43593
43824
|
quotaChangeHistory: () => quotaChangeHistory,
|
|
43825
|
+
referralCodes: () => referralCodes,
|
|
43826
|
+
referrals: () => referrals,
|
|
43594
43827
|
refinementStatusEnum: () => refinementStatusEnum,
|
|
43595
43828
|
refundAuditLog: () => refundAuditLog2,
|
|
43596
43829
|
refundAuditLogRelations: () => refundAuditLogRelations2,
|
|
@@ -43613,7 +43846,6 @@ __export(schema_exports, {
|
|
|
43613
43846
|
securityEventCategoryEnum: () => securityEventCategoryEnum,
|
|
43614
43847
|
securityEventResultEnum: () => securityEventResultEnum,
|
|
43615
43848
|
securityEventTypeEnum: () => securityEventTypeEnum,
|
|
43616
|
-
selectPlatformSettingSchema: () => selectPlatformSettingSchema,
|
|
43617
43849
|
serviceTypeEnum: () => serviceTypeEnum,
|
|
43618
43850
|
sessionCancelledReasonEnum: () => sessionCancelledReasonEnum,
|
|
43619
43851
|
sessionParticipants: () => sessionParticipants2,
|
|
@@ -43629,9 +43861,6 @@ __export(schema_exports, {
|
|
|
43629
43861
|
sessionWaitlistRelations: () => sessionWaitlistRelations2,
|
|
43630
43862
|
sessions: () => sessions,
|
|
43631
43863
|
sessionsRelations: () => sessionsRelations2,
|
|
43632
|
-
settingCategories: () => settingCategories,
|
|
43633
|
-
settingKeys: () => settingKeys,
|
|
43634
|
-
settingValueTypes: () => settingValueTypes,
|
|
43635
43864
|
skillLevelEnum: () => skillLevelEnum,
|
|
43636
43865
|
slaStatusEnum: () => slaStatusEnum,
|
|
43637
43866
|
slashCommandAnalytics: () => slashCommandAnalytics2,
|
|
@@ -43641,7 +43870,6 @@ __export(schema_exports, {
|
|
|
43641
43870
|
sparkChatSessions: () => sparkChatSessions2,
|
|
43642
43871
|
sparkChatSessionsRelations: () => sparkChatSessionsRelations2,
|
|
43643
43872
|
sparkPhaseValues: () => sparkPhaseValues,
|
|
43644
|
-
stringifySettingValue: () => stringifySettingValue,
|
|
43645
43873
|
studentCourseMemory: () => studentCourseMemory,
|
|
43646
43874
|
studentCourseMemoryRelations: () => studentCourseMemoryRelations,
|
|
43647
43875
|
studentFeedback: () => studentFeedback,
|
|
@@ -43699,6 +43927,9 @@ __export(schema_exports, {
|
|
|
43699
43927
|
userBadgesRelations: () => userBadgesRelations2,
|
|
43700
43928
|
userChallengeScores: () => userChallengeScores,
|
|
43701
43929
|
userChallengeScoresRelations: () => userChallengeScoresRelations,
|
|
43930
|
+
userConsentDocumentEnum: () => userConsentDocumentEnum,
|
|
43931
|
+
userConsentSurfaceEnum: () => userConsentSurfaceEnum,
|
|
43932
|
+
userConsents: () => userConsents,
|
|
43702
43933
|
userDeletionStatusEnum: () => userDeletionStatusEnum,
|
|
43703
43934
|
userDeletions: () => userDeletions,
|
|
43704
43935
|
userFollows: () => userFollows2,
|
|
@@ -43758,6 +43989,7 @@ var init_schema3 = __esm({
|
|
|
43758
43989
|
init_creator_index();
|
|
43759
43990
|
init_webhook_events();
|
|
43760
43991
|
init_transactions();
|
|
43992
|
+
init_pix_charges();
|
|
43761
43993
|
init_coupons();
|
|
43762
43994
|
init_coupon_usages();
|
|
43763
43995
|
init_onboarding_analytics();
|
|
@@ -43770,8 +44002,6 @@ var init_schema3 = __esm({
|
|
|
43770
44002
|
init_user_follows();
|
|
43771
44003
|
init_spark_chat_sessions();
|
|
43772
44004
|
init_study_index();
|
|
43773
|
-
init_platform_settings();
|
|
43774
|
-
init_admin_settings_audit();
|
|
43775
44005
|
init_admin_activity_feed();
|
|
43776
44006
|
init_generation_state();
|
|
43777
44007
|
init_security_audit_log();
|
|
@@ -43819,7 +44049,6 @@ var init_schema3 = __esm({
|
|
|
43819
44049
|
init_relations_community();
|
|
43820
44050
|
init_relations_gamification();
|
|
43821
44051
|
init_moderation_log();
|
|
43822
|
-
init_admin_settings_audit();
|
|
43823
44052
|
init_creator_audit_log();
|
|
43824
44053
|
init_banks();
|
|
43825
44054
|
init_course_qa_reports();
|
|
@@ -43841,11 +44070,14 @@ var init_schema3 = __esm({
|
|
|
43841
44070
|
init_course_visibility();
|
|
43842
44071
|
init_course_allowlist();
|
|
43843
44072
|
init_idempotency();
|
|
44073
|
+
init_referrals();
|
|
44074
|
+
init_user_consents();
|
|
43844
44075
|
init_user_deletions();
|
|
43845
44076
|
init_user_profiles();
|
|
43846
44077
|
init_user_resource_audits();
|
|
43847
44078
|
init_email_delivery();
|
|
43848
44079
|
init_subscription_redemptions();
|
|
44080
|
+
init_operation_billing_rates();
|
|
43849
44081
|
}
|
|
43850
44082
|
});
|
|
43851
44083
|
|
|
@@ -43907,7 +44139,6 @@ var init_src3 = __esm({
|
|
|
43907
44139
|
init_user_follows();
|
|
43908
44140
|
init_generation_state();
|
|
43909
44141
|
init_community();
|
|
43910
|
-
init_platform_settings();
|
|
43911
44142
|
init_marketing();
|
|
43912
44143
|
init_security_audit_log();
|
|
43913
44144
|
init_credit_movement_audit_log();
|
|
@@ -44246,7 +44477,7 @@ async function runStart(opts, deps = defaultDeps3) {
|
|
|
44246
44477
|
deps.error(msg);
|
|
44247
44478
|
}
|
|
44248
44479
|
}
|
|
44249
|
-
var
|
|
44480
|
+
var logger10, defaultDeps3, startCommand;
|
|
44250
44481
|
var init_start = __esm({
|
|
44251
44482
|
"src/commands/start.ts"() {
|
|
44252
44483
|
"use strict";
|
|
@@ -44259,7 +44490,7 @@ var init_start = __esm({
|
|
|
44259
44490
|
init_status();
|
|
44260
44491
|
init_formatter();
|
|
44261
44492
|
init_errors();
|
|
44262
|
-
|
|
44493
|
+
logger10 = createLogger("cli:start");
|
|
44263
44494
|
defaultDeps3 = {
|
|
44264
44495
|
requireSession,
|
|
44265
44496
|
requireActiveCourse,
|
|
@@ -44273,7 +44504,7 @@ var init_start = __esm({
|
|
|
44273
44504
|
output,
|
|
44274
44505
|
error,
|
|
44275
44506
|
stderrWrite: (message) => process.stderr.write(message),
|
|
44276
|
-
logger:
|
|
44507
|
+
logger: logger10
|
|
44277
44508
|
};
|
|
44278
44509
|
startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44279
44510
|
await runStart(opts);
|
|
@@ -44283,7 +44514,7 @@ var init_start = __esm({
|
|
|
44283
44514
|
|
|
44284
44515
|
// src/commands/start-next.ts
|
|
44285
44516
|
import { Command as Command9 } from "commander";
|
|
44286
|
-
var
|
|
44517
|
+
var logger11, startNextCommand;
|
|
44287
44518
|
var init_start_next = __esm({
|
|
44288
44519
|
"src/commands/start-next.ts"() {
|
|
44289
44520
|
"use strict";
|
|
@@ -44295,7 +44526,7 @@ var init_start_next = __esm({
|
|
|
44295
44526
|
init_workspace_state();
|
|
44296
44527
|
init_formatter();
|
|
44297
44528
|
init_errors();
|
|
44298
|
-
|
|
44529
|
+
logger11 = createLogger("cli:start-next");
|
|
44299
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) => {
|
|
44300
44531
|
try {
|
|
44301
44532
|
const session = await requireSession();
|
|
@@ -44303,7 +44534,7 @@ var init_start_next = __esm({
|
|
|
44303
44534
|
const driftWarning = await checkCourseDrift();
|
|
44304
44535
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44305
44536
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44306
|
-
const deps = { data, logger:
|
|
44537
|
+
const deps = { data, logger: logger11 };
|
|
44307
44538
|
const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
44308
44539
|
const ws = await findWorkspaceState();
|
|
44309
44540
|
if (ws)
|
|
@@ -44340,7 +44571,7 @@ var init_start_next = __esm({
|
|
|
44340
44571
|
|
|
44341
44572
|
// src/commands/next.ts
|
|
44342
44573
|
import { Command as Command10 } from "commander";
|
|
44343
|
-
var
|
|
44574
|
+
var logger12, nextCommand;
|
|
44344
44575
|
var init_next = __esm({
|
|
44345
44576
|
"src/commands/next.ts"() {
|
|
44346
44577
|
"use strict";
|
|
@@ -44352,7 +44583,7 @@ var init_next = __esm({
|
|
|
44352
44583
|
init_workspace_state();
|
|
44353
44584
|
init_formatter();
|
|
44354
44585
|
init_errors();
|
|
44355
|
-
|
|
44586
|
+
logger12 = createLogger("cli:next");
|
|
44356
44587
|
nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44357
44588
|
try {
|
|
44358
44589
|
const session = await requireSession();
|
|
@@ -44360,7 +44591,7 @@ var init_next = __esm({
|
|
|
44360
44591
|
const driftWarning = await checkCourseDrift();
|
|
44361
44592
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44362
44593
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44363
|
-
const deps = { data, logger:
|
|
44594
|
+
const deps = { data, logger: logger12 };
|
|
44364
44595
|
const lessonData = await nextLesson(
|
|
44365
44596
|
{ enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
|
|
44366
44597
|
deps
|
|
@@ -44433,7 +44664,7 @@ function replacePlaceholders(text2, workspacePath, courseTitle) {
|
|
|
44433
44664
|
const base = path13.basename(workspacePath) === ".tostudy" ? path13.dirname(workspacePath) : workspacePath;
|
|
44434
44665
|
const slug = courseSlug(courseTitle);
|
|
44435
44666
|
const vaultPath = resolveVaultPath(workspacePath, slug);
|
|
44436
|
-
return text2.
|
|
44667
|
+
return text2.replace(/\$WORKSPACE(?![A-Za-z0-9_])/g, () => base).replace(/\$VAULT(?![A-Za-z0-9_])/g, () => vaultPath);
|
|
44437
44668
|
}
|
|
44438
44669
|
function formatLessonContent(data, workspacePath, courseTitle) {
|
|
44439
44670
|
const time4 = adjustTimeEstimate(data.type, data.estimatedTimeMinutes);
|
|
@@ -44474,7 +44705,7 @@ function formatLessonContent(data, workspacePath, courseTitle) {
|
|
|
44474
44705
|
}
|
|
44475
44706
|
return lines.join("\n");
|
|
44476
44707
|
}
|
|
44477
|
-
var
|
|
44708
|
+
var logger13, lessonCommand;
|
|
44478
44709
|
var init_lesson = __esm({
|
|
44479
44710
|
"src/commands/lesson.ts"() {
|
|
44480
44711
|
"use strict";
|
|
@@ -44487,7 +44718,7 @@ var init_lesson = __esm({
|
|
|
44487
44718
|
init_formatter();
|
|
44488
44719
|
init_resolve();
|
|
44489
44720
|
init_errors();
|
|
44490
|
-
|
|
44721
|
+
logger13 = createLogger("cli:lesson");
|
|
44491
44722
|
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").option(
|
|
44492
44723
|
"--read <lessonId>",
|
|
44493
44724
|
"Read a specific lesson by id (works on archived / read-only courses)"
|
|
@@ -44498,7 +44729,7 @@ var init_lesson = __esm({
|
|
|
44498
44729
|
const driftWarning = await checkCourseDrift();
|
|
44499
44730
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44500
44731
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44501
|
-
const deps = { data, logger:
|
|
44732
|
+
const deps = { data, logger: logger13 };
|
|
44502
44733
|
let lessonId = opts.read ?? activeCourse.currentLessonId;
|
|
44503
44734
|
if (!lessonId) {
|
|
44504
44735
|
try {
|
|
@@ -44593,7 +44824,7 @@ function formatKnowledge(data) {
|
|
|
44593
44824
|
});
|
|
44594
44825
|
return lines.join("\n").trimEnd();
|
|
44595
44826
|
}
|
|
44596
|
-
var
|
|
44827
|
+
var logger14, knowledgeCommand;
|
|
44597
44828
|
var init_knowledge2 = __esm({
|
|
44598
44829
|
"src/commands/knowledge.ts"() {
|
|
44599
44830
|
"use strict";
|
|
@@ -44601,7 +44832,7 @@ var init_knowledge2 = __esm({
|
|
|
44601
44832
|
init_http();
|
|
44602
44833
|
init_guards();
|
|
44603
44834
|
init_formatter();
|
|
44604
|
-
|
|
44835
|
+
logger14 = createLogger("cli:knowledge");
|
|
44605
44836
|
knowledgeCommand = new Command12("knowledge").description("Show the active course's knowledge base (base de conhecimento)").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44606
44837
|
try {
|
|
44607
44838
|
const activeCourse = await requireActiveCourse();
|
|
@@ -44625,7 +44856,7 @@ var init_knowledge2 = __esm({
|
|
|
44625
44856
|
else error(msg);
|
|
44626
44857
|
return;
|
|
44627
44858
|
}
|
|
44628
|
-
|
|
44859
|
+
logger14.warn("knowledge failed", { error: msg });
|
|
44629
44860
|
if (opts.json) jsonError(msg);
|
|
44630
44861
|
else error(msg);
|
|
44631
44862
|
}
|
|
@@ -44635,7 +44866,7 @@ var init_knowledge2 = __esm({
|
|
|
44635
44866
|
|
|
44636
44867
|
// src/commands/hint.ts
|
|
44637
44868
|
import { Command as Command13 } from "commander";
|
|
44638
|
-
var
|
|
44869
|
+
var logger15, hintCommand;
|
|
44639
44870
|
var init_hint = __esm({
|
|
44640
44871
|
"src/commands/hint.ts"() {
|
|
44641
44872
|
"use strict";
|
|
@@ -44646,7 +44877,7 @@ var init_hint = __esm({
|
|
|
44646
44877
|
init_course_state();
|
|
44647
44878
|
init_formatter();
|
|
44648
44879
|
init_errors();
|
|
44649
|
-
|
|
44880
|
+
logger15 = createLogger("cli:hint");
|
|
44650
44881
|
hintCommand = new Command13("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44651
44882
|
try {
|
|
44652
44883
|
const session = await requireSession();
|
|
@@ -44654,7 +44885,7 @@ var init_hint = __esm({
|
|
|
44654
44885
|
const driftWarning = await checkCourseDrift();
|
|
44655
44886
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44656
44887
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44657
|
-
const deps = { data, logger:
|
|
44888
|
+
const deps = { data, logger: logger15 };
|
|
44658
44889
|
const hint = await getHint(
|
|
44659
44890
|
{ userId: session.userId, enrollmentId: activeCourse.enrollmentId },
|
|
44660
44891
|
deps
|
|
@@ -45008,7 +45239,7 @@ var init_init_template = __esm({
|
|
|
45008
45239
|
import fs12 from "node:fs";
|
|
45009
45240
|
import path14 from "node:path";
|
|
45010
45241
|
import { Command as Command14 } from "commander";
|
|
45011
|
-
var
|
|
45242
|
+
var logger16, validateCommand;
|
|
45012
45243
|
var init_validate = __esm({
|
|
45013
45244
|
"src/commands/validate.ts"() {
|
|
45014
45245
|
"use strict";
|
|
@@ -45021,7 +45252,7 @@ var init_validate = __esm({
|
|
|
45021
45252
|
init_formatter();
|
|
45022
45253
|
init_init_template();
|
|
45023
45254
|
init_errors();
|
|
45024
|
-
|
|
45255
|
+
logger16 = createLogger("cli:validate");
|
|
45025
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) => {
|
|
45026
45257
|
try {
|
|
45027
45258
|
const session = await requireSession();
|
|
@@ -45029,7 +45260,7 @@ var init_validate = __esm({
|
|
|
45029
45260
|
const driftWarning = await checkCourseDrift();
|
|
45030
45261
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
45031
45262
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
45032
|
-
const deps = { data, logger:
|
|
45263
|
+
const deps = { data, logger: logger16 };
|
|
45033
45264
|
let lessonId = activeCourse.currentLessonId;
|
|
45034
45265
|
if (!lessonId) {
|
|
45035
45266
|
try {
|
|
@@ -45478,7 +45709,7 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
|
|
|
45478
45709
|
deps.output(artifacts.learnerBrief, { json: false });
|
|
45479
45710
|
}
|
|
45480
45711
|
}
|
|
45481
|
-
var
|
|
45712
|
+
var logger17, defaultDeps4, initCommand;
|
|
45482
45713
|
var init_init = __esm({
|
|
45483
45714
|
"src/commands/init.ts"() {
|
|
45484
45715
|
"use strict";
|
|
@@ -45494,7 +45725,7 @@ var init_init = __esm({
|
|
|
45494
45725
|
init_api3();
|
|
45495
45726
|
init_instruction_pipeline();
|
|
45496
45727
|
init_pipeline_deps();
|
|
45497
|
-
|
|
45728
|
+
logger17 = createLogger("cli:init");
|
|
45498
45729
|
defaultDeps4 = {
|
|
45499
45730
|
getSession,
|
|
45500
45731
|
findWorkspaceState,
|
|
@@ -45508,7 +45739,7 @@ var init_init = __esm({
|
|
|
45508
45739
|
saveCourseLearnerProfile,
|
|
45509
45740
|
buildInitArtifacts,
|
|
45510
45741
|
output,
|
|
45511
|
-
logger:
|
|
45742
|
+
logger: logger17,
|
|
45512
45743
|
createHttpProvider,
|
|
45513
45744
|
resolveAndGenerate,
|
|
45514
45745
|
buildPipelineDeps
|
|
@@ -45830,7 +46061,7 @@ import { Command as Command17 } from "commander";
|
|
|
45830
46061
|
import path17 from "node:path";
|
|
45831
46062
|
import os9 from "node:os";
|
|
45832
46063
|
import fs15 from "node:fs/promises";
|
|
45833
|
-
var
|
|
46064
|
+
var logger18, workspaceCommand;
|
|
45834
46065
|
var init_workspace2 = __esm({
|
|
45835
46066
|
"src/commands/workspace.ts"() {
|
|
45836
46067
|
"use strict";
|
|
@@ -45840,7 +46071,7 @@ var init_workspace2 = __esm({
|
|
|
45840
46071
|
init_course_state();
|
|
45841
46072
|
init_resolve();
|
|
45842
46073
|
init_errors();
|
|
45843
|
-
|
|
46074
|
+
logger18 = createLogger("cli:workspace");
|
|
45844
46075
|
workspaceCommand = new Command17("workspace").description(
|
|
45845
46076
|
getErrors().workspaceCommandDescription
|
|
45846
46077
|
);
|
|
@@ -45906,7 +46137,7 @@ Pr\xF3ximo passo: tostudy export
|
|
|
45906
46137
|
);
|
|
45907
46138
|
}
|
|
45908
46139
|
} catch (err) {
|
|
45909
|
-
|
|
46140
|
+
logger18.error("workspace setup failed", { error: err });
|
|
45910
46141
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
45911
46142
|
`);
|
|
45912
46143
|
process.exit(1);
|
|
@@ -46014,7 +46245,7 @@ import { Command as Command18 } from "commander";
|
|
|
46014
46245
|
import path18 from "node:path";
|
|
46015
46246
|
import os10 from "node:os";
|
|
46016
46247
|
import fs16 from "node:fs/promises";
|
|
46017
|
-
var
|
|
46248
|
+
var logger19, exportCommand;
|
|
46018
46249
|
var init_export = __esm({
|
|
46019
46250
|
"src/commands/export.ts"() {
|
|
46020
46251
|
"use strict";
|
|
@@ -46025,7 +46256,7 @@ var init_export = __esm({
|
|
|
46025
46256
|
init_course_state();
|
|
46026
46257
|
init_resolve();
|
|
46027
46258
|
init_errors();
|
|
46028
|
-
|
|
46259
|
+
logger19 = createLogger("cli:export");
|
|
46029
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) => {
|
|
46030
46261
|
try {
|
|
46031
46262
|
const session = await requireSession();
|
|
@@ -46053,7 +46284,7 @@ var init_export = __esm({
|
|
|
46053
46284
|
}
|
|
46054
46285
|
if (!hasConfig) {
|
|
46055
46286
|
const slug = courseSlug(activeCourse.courseTitle);
|
|
46056
|
-
|
|
46287
|
+
logger19.info("Auto-initializing workspace", { workspacePath: ws.workspacePath });
|
|
46057
46288
|
await fs16.mkdir(ws.workspacePath, { recursive: true });
|
|
46058
46289
|
for (const dir of ["exercises", "generated", "notes", "diagrams"]) {
|
|
46059
46290
|
await fs16.mkdir(path18.join(ws.workspacePath, dir), { recursive: true });
|
|
@@ -46115,7 +46346,7 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
|
|
|
46115
46346
|
);
|
|
46116
46347
|
}
|
|
46117
46348
|
} catch (err) {
|
|
46118
|
-
|
|
46349
|
+
logger19.error("export failed", { error: err });
|
|
46119
46350
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46120
46351
|
`);
|
|
46121
46352
|
process.exit(1);
|
|
@@ -46129,7 +46360,7 @@ import { Command as Command19 } from "commander";
|
|
|
46129
46360
|
import { execFile as execFile3 } from "node:child_process";
|
|
46130
46361
|
import path19 from "node:path";
|
|
46131
46362
|
import os11 from "node:os";
|
|
46132
|
-
var
|
|
46363
|
+
var logger20, openCommand;
|
|
46133
46364
|
var init_open = __esm({
|
|
46134
46365
|
"src/commands/open.ts"() {
|
|
46135
46366
|
"use strict";
|
|
@@ -46138,7 +46369,7 @@ var init_open = __esm({
|
|
|
46138
46369
|
init_course_state();
|
|
46139
46370
|
init_resolve();
|
|
46140
46371
|
init_errors();
|
|
46141
|
-
|
|
46372
|
+
logger20 = createLogger("cli:open");
|
|
46142
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) => {
|
|
46143
46374
|
try {
|
|
46144
46375
|
const activeCourse = await requireActiveCourse();
|
|
@@ -46156,7 +46387,7 @@ var init_open = __esm({
|
|
|
46156
46387
|
const editor = process.env["EDITOR"] ?? "code";
|
|
46157
46388
|
execFile3(editor, [ws.workspacePath], (err) => {
|
|
46158
46389
|
if (err) {
|
|
46159
|
-
|
|
46390
|
+
logger20.error("open failed", { editor, workspacePath: ws.workspacePath });
|
|
46160
46391
|
process.stderr.write(`\u274C Falha ao abrir: ${err.message}
|
|
46161
46392
|
`);
|
|
46162
46393
|
process.exit(1);
|
|
@@ -46165,7 +46396,7 @@ var init_open = __esm({
|
|
|
46165
46396
|
`);
|
|
46166
46397
|
});
|
|
46167
46398
|
} catch (err) {
|
|
46168
|
-
|
|
46399
|
+
logger20.error("open command failed", { error: err });
|
|
46169
46400
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46170
46401
|
`);
|
|
46171
46402
|
process.exit(1);
|
|
@@ -46237,7 +46468,7 @@ import { Command as Command20 } from "commander";
|
|
|
46237
46468
|
import path21 from "node:path";
|
|
46238
46469
|
import os12 from "node:os";
|
|
46239
46470
|
import fs18 from "node:fs/promises";
|
|
46240
|
-
var
|
|
46471
|
+
var logger21, vaultCommand;
|
|
46241
46472
|
var init_vault2 = __esm({
|
|
46242
46473
|
"src/commands/vault.ts"() {
|
|
46243
46474
|
"use strict";
|
|
@@ -46249,7 +46480,7 @@ var init_vault2 = __esm({
|
|
|
46249
46480
|
init_course_state();
|
|
46250
46481
|
init_resolve();
|
|
46251
46482
|
init_errors();
|
|
46252
|
-
|
|
46483
|
+
logger21 = createLogger("cli:vault");
|
|
46253
46484
|
vaultCommand = new Command20("vault").description("Gerenciar vault Obsidian do curso");
|
|
46254
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) => {
|
|
46255
46486
|
try {
|
|
@@ -46294,7 +46525,7 @@ var init_vault2 = __esm({
|
|
|
46294
46525
|
activeCourse.courseId,
|
|
46295
46526
|
slug
|
|
46296
46527
|
);
|
|
46297
|
-
|
|
46528
|
+
logger21.info("Vault generated", {
|
|
46298
46529
|
courseId: activeCourse.courseId,
|
|
46299
46530
|
vaultPath: result.vaultPath,
|
|
46300
46531
|
filesWritten: result.filesWritten
|
|
@@ -46327,7 +46558,7 @@ Para visualizar:
|
|
|
46327
46558
|
);
|
|
46328
46559
|
}
|
|
46329
46560
|
} catch (err) {
|
|
46330
|
-
|
|
46561
|
+
logger21.error("vault init failed", { error: err });
|
|
46331
46562
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46332
46563
|
`);
|
|
46333
46564
|
process.exit(1);
|
|
@@ -46357,7 +46588,7 @@ Para visualizar:
|
|
|
46357
46588
|
process.exit(1);
|
|
46358
46589
|
}
|
|
46359
46590
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
46360
|
-
const deps = { data, logger:
|
|
46591
|
+
const deps = { data, logger: logger21 };
|
|
46361
46592
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
46362
46593
|
const markerPath = path21.join(vaultPath, ".ana-vault.json");
|
|
46363
46594
|
const markerRaw = await fs18.readFile(markerPath, "utf-8");
|
|
@@ -46411,7 +46642,7 @@ Para visualizar:
|
|
|
46411
46642
|
);
|
|
46412
46643
|
}
|
|
46413
46644
|
} catch (err) {
|
|
46414
|
-
|
|
46645
|
+
logger21.error("vault sync failed", { error: err });
|
|
46415
46646
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46416
46647
|
`);
|
|
46417
46648
|
process.exit(1);
|
|
@@ -46491,7 +46722,7 @@ var init_profile = __esm({
|
|
|
46491
46722
|
|
|
46492
46723
|
// src/commands/sync.ts
|
|
46493
46724
|
import { Command as Command22 } from "commander";
|
|
46494
|
-
var
|
|
46725
|
+
var logger22, syncCommand;
|
|
46495
46726
|
var init_sync = __esm({
|
|
46496
46727
|
"src/commands/sync.ts"() {
|
|
46497
46728
|
"use strict";
|
|
@@ -46500,15 +46731,18 @@ var init_sync = __esm({
|
|
|
46500
46731
|
init_formatter();
|
|
46501
46732
|
init_instruction_pipeline();
|
|
46502
46733
|
init_pipeline_deps();
|
|
46503
|
-
|
|
46504
|
-
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) => {
|
|
46505
46739
|
try {
|
|
46506
46740
|
await requireSession();
|
|
46507
46741
|
const activeCourse = await requireActiveCourse();
|
|
46508
46742
|
const pipelineResult = await resolveAndGenerate(
|
|
46509
46743
|
{ courseId: activeCourse.courseId, enrollmentId: activeCourse.enrollmentId },
|
|
46510
46744
|
{ forceRefresh: true, collectT1Interactive: false, collectT2Interactive: false },
|
|
46511
|
-
{ cwd: process.cwd(), deps: buildPipelineDeps() }
|
|
46745
|
+
{ cwd: process.cwd(), deps: buildPipelineDeps({ allRuntimes: opts.allRuntimes }) }
|
|
46512
46746
|
);
|
|
46513
46747
|
if (opts.json) {
|
|
46514
46748
|
output(
|
|
@@ -46539,7 +46773,7 @@ var init_sync = __esm({
|
|
|
46539
46773
|
} catch (err) {
|
|
46540
46774
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46541
46775
|
if (msg.includes("process.exit")) return;
|
|
46542
|
-
|
|
46776
|
+
logger22.warn("sync failed", { error: msg });
|
|
46543
46777
|
error(msg);
|
|
46544
46778
|
}
|
|
46545
46779
|
});
|
|
@@ -46548,7 +46782,7 @@ var init_sync = __esm({
|
|
|
46548
46782
|
|
|
46549
46783
|
// src/commands/brief.ts
|
|
46550
46784
|
import { Command as Command23 } from "commander";
|
|
46551
|
-
var
|
|
46785
|
+
var logger23, briefCommand;
|
|
46552
46786
|
var init_brief = __esm({
|
|
46553
46787
|
"src/commands/brief.ts"() {
|
|
46554
46788
|
"use strict";
|
|
@@ -46557,7 +46791,7 @@ var init_brief = __esm({
|
|
|
46557
46791
|
init_cache();
|
|
46558
46792
|
init_api();
|
|
46559
46793
|
init_formatter();
|
|
46560
|
-
|
|
46794
|
+
logger23 = createLogger("cli:brief");
|
|
46561
46795
|
briefCommand = new Command23("brief").description("Show your base learner brief (T1) status and content").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46562
46796
|
try {
|
|
46563
46797
|
const session = await requireSession();
|
|
@@ -46591,7 +46825,7 @@ var init_brief = __esm({
|
|
|
46591
46825
|
}
|
|
46592
46826
|
output(lines.join("\n"), { json: false });
|
|
46593
46827
|
} catch (err) {
|
|
46594
|
-
|
|
46828
|
+
logger23.error("Failed to show brief", { err });
|
|
46595
46829
|
error(`Erro ao buscar brief: ${err instanceof Error ? err.message : String(err)}`);
|
|
46596
46830
|
}
|
|
46597
46831
|
});
|
|
@@ -46600,7 +46834,7 @@ var init_brief = __esm({
|
|
|
46600
46834
|
|
|
46601
46835
|
// src/commands/brief-create.ts
|
|
46602
46836
|
import { Command as Command24 } from "commander";
|
|
46603
|
-
var
|
|
46837
|
+
var logger24, briefCreateCommand;
|
|
46604
46838
|
var init_brief_create = __esm({
|
|
46605
46839
|
"src/commands/brief-create.ts"() {
|
|
46606
46840
|
"use strict";
|
|
@@ -46610,7 +46844,7 @@ var init_brief_create = __esm({
|
|
|
46610
46844
|
init_api();
|
|
46611
46845
|
init_cache();
|
|
46612
46846
|
init_formatter();
|
|
46613
|
-
|
|
46847
|
+
logger24 = createLogger("cli:brief-create");
|
|
46614
46848
|
briefCreateCommand = new Command24("brief-create").description("Create your base learner brief via interactive prompts (T1 bootstrap)").action(async () => {
|
|
46615
46849
|
try {
|
|
46616
46850
|
const session = await requireSession();
|
|
@@ -46635,7 +46869,7 @@ var init_brief_create = __esm({
|
|
|
46635
46869
|
];
|
|
46636
46870
|
output(doneLines.join("\n"), { json: false });
|
|
46637
46871
|
} catch (err) {
|
|
46638
|
-
|
|
46872
|
+
logger24.error("Failed to create brief", { err });
|
|
46639
46873
|
error(`Erro ao criar brief: ${err instanceof Error ? err.message : String(err)}`);
|
|
46640
46874
|
}
|
|
46641
46875
|
});
|
|
@@ -46700,7 +46934,7 @@ async function saveModuleSummary(workspacePath, input2) {
|
|
|
46700
46934
|
""
|
|
46701
46935
|
].join("\n");
|
|
46702
46936
|
fs19.writeFileSync(filePath, header + input2.summary, { mode: 384 });
|
|
46703
|
-
|
|
46937
|
+
logger25.debug("Module summary saved", { moduleId: input2.moduleId, path: filePath });
|
|
46704
46938
|
return filePath;
|
|
46705
46939
|
}
|
|
46706
46940
|
async function loadSessionContext(workspacePath) {
|
|
@@ -46721,19 +46955,19 @@ async function loadSessionContext(workspacePath) {
|
|
|
46721
46955
|
}
|
|
46722
46956
|
return { moduleSummaries: summaries };
|
|
46723
46957
|
}
|
|
46724
|
-
var
|
|
46958
|
+
var logger25;
|
|
46725
46959
|
var init_storage = __esm({
|
|
46726
46960
|
"src/sessions/storage.ts"() {
|
|
46727
46961
|
"use strict";
|
|
46728
46962
|
init_dist();
|
|
46729
|
-
|
|
46963
|
+
logger25 = createLogger("cli:sessions");
|
|
46730
46964
|
}
|
|
46731
46965
|
});
|
|
46732
46966
|
|
|
46733
46967
|
// src/commands/compact.ts
|
|
46734
46968
|
import fs20 from "node:fs";
|
|
46735
46969
|
import { Command as Command26 } from "commander";
|
|
46736
|
-
var
|
|
46970
|
+
var logger26, compactCommand;
|
|
46737
46971
|
var init_compact = __esm({
|
|
46738
46972
|
"src/commands/compact.ts"() {
|
|
46739
46973
|
"use strict";
|
|
@@ -46742,7 +46976,7 @@ var init_compact = __esm({
|
|
|
46742
46976
|
init_workspace_state();
|
|
46743
46977
|
init_storage();
|
|
46744
46978
|
init_formatter();
|
|
46745
|
-
|
|
46979
|
+
logger26 = createLogger("cli:compact");
|
|
46746
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) => {
|
|
46747
46981
|
try {
|
|
46748
46982
|
const activeCourse = await requireActiveCourse();
|
|
@@ -46763,7 +46997,7 @@ var init_compact = __esm({
|
|
|
46763
46997
|
moduleTitle,
|
|
46764
46998
|
summary
|
|
46765
46999
|
});
|
|
46766
|
-
|
|
47000
|
+
logger26.debug("Compact summary saved", { moduleId, filePath });
|
|
46767
47001
|
if (opts.json) {
|
|
46768
47002
|
output({ saved: true, path: filePath, moduleId }, { json: true });
|
|
46769
47003
|
} else {
|
|
@@ -46772,7 +47006,7 @@ var init_compact = __esm({
|
|
|
46772
47006
|
} catch (err) {
|
|
46773
47007
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46774
47008
|
if (msg.includes("process.exit")) return;
|
|
46775
|
-
|
|
47009
|
+
logger26.warn("compact failed", { error: msg });
|
|
46776
47010
|
if (opts.json) jsonError(msg);
|
|
46777
47011
|
error(msg);
|
|
46778
47012
|
}
|
|
@@ -46782,7 +47016,7 @@ var init_compact = __esm({
|
|
|
46782
47016
|
|
|
46783
47017
|
// src/commands/context.ts
|
|
46784
47018
|
import { Command as Command27 } from "commander";
|
|
46785
|
-
var
|
|
47019
|
+
var logger27, contextCommand;
|
|
46786
47020
|
var init_context = __esm({
|
|
46787
47021
|
"src/commands/context.ts"() {
|
|
46788
47022
|
"use strict";
|
|
@@ -46790,7 +47024,7 @@ var init_context = __esm({
|
|
|
46790
47024
|
init_workspace_state();
|
|
46791
47025
|
init_storage();
|
|
46792
47026
|
init_formatter();
|
|
46793
|
-
|
|
47027
|
+
logger27 = createLogger("cli:context");
|
|
46794
47028
|
contextCommand = new Command27("context").description("Load session context (workspace state + module summaries) for LLM consumption").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46795
47029
|
try {
|
|
46796
47030
|
const ws = await findWorkspaceState();
|
|
@@ -46818,7 +47052,7 @@ var init_context = __esm({
|
|
|
46818
47052
|
})),
|
|
46819
47053
|
totalModulesCompleted: sessionCtx.moduleSummaries.length
|
|
46820
47054
|
};
|
|
46821
|
-
|
|
47055
|
+
logger27.debug("Context loaded", {
|
|
46822
47056
|
courseId: ws.state.courseId,
|
|
46823
47057
|
moduleSummaries: sessionCtx.moduleSummaries.length
|
|
46824
47058
|
});
|
|
@@ -46832,7 +47066,7 @@ var init_context = __esm({
|
|
|
46832
47066
|
} catch (err) {
|
|
46833
47067
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46834
47068
|
if (msg.includes("process.exit")) return;
|
|
46835
|
-
|
|
47069
|
+
logger27.warn("context failed", { error: msg });
|
|
46836
47070
|
if (opts.json) jsonError(msg);
|
|
46837
47071
|
error(msg);
|
|
46838
47072
|
}
|
|
@@ -46842,7 +47076,7 @@ var init_context = __esm({
|
|
|
46842
47076
|
|
|
46843
47077
|
// src/commands/memory.ts
|
|
46844
47078
|
import { Command as Command28 } from "commander";
|
|
46845
|
-
var
|
|
47079
|
+
var logger28, memoryCommand;
|
|
46846
47080
|
var init_memory = __esm({
|
|
46847
47081
|
"src/commands/memory.ts"() {
|
|
46848
47082
|
"use strict";
|
|
@@ -46851,7 +47085,7 @@ var init_memory = __esm({
|
|
|
46851
47085
|
init_workspace_state();
|
|
46852
47086
|
init_guards();
|
|
46853
47087
|
init_formatter();
|
|
46854
|
-
|
|
47088
|
+
logger28 = createLogger("cli:memory");
|
|
46855
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) => {
|
|
46856
47090
|
try {
|
|
46857
47091
|
const ws = await findWorkspaceState();
|
|
@@ -46875,7 +47109,7 @@ var init_memory = __esm({
|
|
|
46875
47109
|
} catch (err) {
|
|
46876
47110
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46877
47111
|
if (msg.includes("process.exit")) return;
|
|
46878
|
-
|
|
47112
|
+
logger28.warn("memory failed", { error: msg });
|
|
46879
47113
|
if (opts.json) jsonError(msg);
|
|
46880
47114
|
else error(msg);
|
|
46881
47115
|
}
|
|
@@ -46885,7 +47119,7 @@ var init_memory = __esm({
|
|
|
46885
47119
|
|
|
46886
47120
|
// src/commands/insight.ts
|
|
46887
47121
|
import { Command as Command29 } from "commander";
|
|
46888
|
-
var
|
|
47122
|
+
var logger29, VALID_TYPES, insightCommand;
|
|
46889
47123
|
var init_insight = __esm({
|
|
46890
47124
|
"src/commands/insight.ts"() {
|
|
46891
47125
|
"use strict";
|
|
@@ -46894,7 +47128,7 @@ var init_insight = __esm({
|
|
|
46894
47128
|
init_workspace_state();
|
|
46895
47129
|
init_guards();
|
|
46896
47130
|
init_formatter();
|
|
46897
|
-
|
|
47131
|
+
logger29 = createLogger("cli:insight");
|
|
46898
47132
|
VALID_TYPES = ["difficulty", "breakthrough", "question"];
|
|
46899
47133
|
insightCommand = new Command29("insight").description(
|
|
46900
47134
|
"Persist a student cognitive insight (difficulty | breakthrough | question) into course memory"
|
|
@@ -46936,7 +47170,7 @@ var init_insight = __esm({
|
|
|
46936
47170
|
} catch (err) {
|
|
46937
47171
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46938
47172
|
if (msg.includes("process.exit")) return;
|
|
46939
|
-
|
|
47173
|
+
logger29.warn("insight failed", { error: msg });
|
|
46940
47174
|
if (opts.json) jsonError(msg);
|
|
46941
47175
|
else error(msg);
|
|
46942
47176
|
}
|
|
@@ -46949,7 +47183,7 @@ import { Command as Command30 } from "commander";
|
|
|
46949
47183
|
function isExerciseLevel2(value) {
|
|
46950
47184
|
return ALL_LEVELS.includes(value);
|
|
46951
47185
|
}
|
|
46952
|
-
var
|
|
47186
|
+
var logger30, ALL_LEVELS, LEVEL_LABELS2, levelCommand;
|
|
46953
47187
|
var init_level = __esm({
|
|
46954
47188
|
"src/commands/level.ts"() {
|
|
46955
47189
|
"use strict";
|
|
@@ -46958,7 +47192,7 @@ var init_level = __esm({
|
|
|
46958
47192
|
init_exercises();
|
|
46959
47193
|
init_guards();
|
|
46960
47194
|
init_formatter();
|
|
46961
|
-
|
|
47195
|
+
logger30 = createLogger("cli:level");
|
|
46962
47196
|
ALL_LEVELS = ["L0", "L1", "L2", "L3", "L4"];
|
|
46963
47197
|
LEVEL_LABELS2 = {
|
|
46964
47198
|
L0: "Pr\xE9-check (perguntas conceituais)",
|
|
@@ -46972,7 +47206,7 @@ var init_level = __esm({
|
|
|
46972
47206
|
const session = await requireSession();
|
|
46973
47207
|
const activeCourse = await requireActiveCourse();
|
|
46974
47208
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
46975
|
-
const deps = { data, logger:
|
|
47209
|
+
const deps = { data, logger: logger30 };
|
|
46976
47210
|
if (!rawLevel) {
|
|
46977
47211
|
const levels = await getEnrollmentLevels({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
46978
47212
|
if (opts.json) {
|
|
@@ -47031,7 +47265,7 @@ var init_level = __esm({
|
|
|
47031
47265
|
|
|
47032
47266
|
// src/commands/theory.ts
|
|
47033
47267
|
import { Command as Command31 } from "commander";
|
|
47034
|
-
var
|
|
47268
|
+
var logger31, EXERCISE_LEVELS2, theoryCommand;
|
|
47035
47269
|
var init_theory = __esm({
|
|
47036
47270
|
"src/commands/theory.ts"() {
|
|
47037
47271
|
"use strict";
|
|
@@ -47039,7 +47273,7 @@ var init_theory = __esm({
|
|
|
47039
47273
|
init_guards();
|
|
47040
47274
|
init_formatter();
|
|
47041
47275
|
init_errors();
|
|
47042
|
-
|
|
47276
|
+
logger31 = createLogger("cli:theory");
|
|
47043
47277
|
EXERCISE_LEVELS2 = ["L0", "L1", "L2", "L3", "L4"];
|
|
47044
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) => {
|
|
47045
47279
|
try {
|
|
@@ -47078,7 +47312,7 @@ var init_theory = __esm({
|
|
|
47078
47312
|
currentLevel = levels.currentLevel;
|
|
47079
47313
|
}
|
|
47080
47314
|
const requestUrl = `${session.apiUrl}/api/cli/exercises/more-theory`;
|
|
47081
|
-
|
|
47315
|
+
logger31.debug("Requesting more theory", { lessonId, currentLevel });
|
|
47082
47316
|
const res = await fetch(requestUrl, {
|
|
47083
47317
|
method: "POST",
|
|
47084
47318
|
headers: {
|
|
@@ -47483,7 +47717,7 @@ async function runExportGrades(opts, deps = defaultDeps5) {
|
|
|
47483
47717
|
if (!rendered.endsWith("\n")) rendered += "\n";
|
|
47484
47718
|
deps.stdoutWrite(rendered);
|
|
47485
47719
|
}
|
|
47486
|
-
var
|
|
47720
|
+
var logger32, SUPPORTED_FORMATS, defaultDeps5, exportGradesCommand;
|
|
47487
47721
|
var init_export_grades = __esm({
|
|
47488
47722
|
"src/commands/export-grades.ts"() {
|
|
47489
47723
|
"use strict";
|
|
@@ -47491,7 +47725,7 @@ var init_export_grades = __esm({
|
|
|
47491
47725
|
init_guards();
|
|
47492
47726
|
init_grades();
|
|
47493
47727
|
init_resolve_enrollment();
|
|
47494
|
-
|
|
47728
|
+
logger32 = createLogger("cli:export-grades");
|
|
47495
47729
|
SUPPORTED_FORMATS = ["json", "csv", "md"];
|
|
47496
47730
|
defaultDeps5 = {
|
|
47497
47731
|
requireSession,
|
|
@@ -47501,7 +47735,7 @@ var init_export_grades = __esm({
|
|
|
47501
47735
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47502
47736
|
// process.exit is typed as `never` — wrap so the cast is local to one line.
|
|
47503
47737
|
exit: (code) => process.exit(code),
|
|
47504
|
-
logger:
|
|
47738
|
+
logger: logger32,
|
|
47505
47739
|
resolveBySlug: resolveEnrollmentBySlug
|
|
47506
47740
|
};
|
|
47507
47741
|
exportGradesCommand = new Command32("export-grades").description("Exporta o hist\xF3rico de valida\xE7\xF5es (notas) do curso ativo").option(
|
|
@@ -47670,7 +47904,7 @@ async function runGrades(opts, deps = defaultDeps6) {
|
|
|
47670
47904
|
);
|
|
47671
47905
|
deps.stdoutWrite(formatGradesAllEnrollmentsTable(summaries) + "\n");
|
|
47672
47906
|
}
|
|
47673
|
-
var
|
|
47907
|
+
var logger33, defaultDeps6, gradesCommand;
|
|
47674
47908
|
var init_grades2 = __esm({
|
|
47675
47909
|
"src/commands/grades.ts"() {
|
|
47676
47910
|
"use strict";
|
|
@@ -47680,14 +47914,14 @@ var init_grades2 = __esm({
|
|
|
47680
47914
|
init_guards();
|
|
47681
47915
|
init_grades();
|
|
47682
47916
|
init_resolve_enrollment();
|
|
47683
|
-
|
|
47917
|
+
logger33 = createLogger("cli:grades");
|
|
47684
47918
|
defaultDeps6 = {
|
|
47685
47919
|
requireSession,
|
|
47686
47920
|
fetch: globalThis.fetch.bind(globalThis),
|
|
47687
47921
|
stdoutWrite: (message) => process.stdout.write(message),
|
|
47688
47922
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47689
47923
|
exit: (code) => process.exit(code),
|
|
47690
|
-
logger:
|
|
47924
|
+
logger: logger33,
|
|
47691
47925
|
resolveBySlug: resolveEnrollmentBySlug,
|
|
47692
47926
|
buildDataProvider: createHttpProvider,
|
|
47693
47927
|
listCoursesFn: listCourses
|
|
@@ -47852,7 +48086,7 @@ async function runReview(slug, opts, deps = defaultDeps7) {
|
|
|
47852
48086
|
}) + "\n"
|
|
47853
48087
|
);
|
|
47854
48088
|
}
|
|
47855
|
-
var
|
|
48089
|
+
var logger34, defaultDeps7, reviewCommand;
|
|
47856
48090
|
var init_review2 = __esm({
|
|
47857
48091
|
"src/commands/review.ts"() {
|
|
47858
48092
|
"use strict";
|
|
@@ -47860,14 +48094,14 @@ var init_review2 = __esm({
|
|
|
47860
48094
|
init_guards();
|
|
47861
48095
|
init_grades();
|
|
47862
48096
|
init_resolve_enrollment();
|
|
47863
|
-
|
|
48097
|
+
logger34 = createLogger("cli:review");
|
|
47864
48098
|
defaultDeps7 = {
|
|
47865
48099
|
requireSession,
|
|
47866
48100
|
fetch: globalThis.fetch.bind(globalThis),
|
|
47867
48101
|
stdoutWrite: (message) => process.stdout.write(message),
|
|
47868
48102
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47869
48103
|
exit: (code) => process.exit(code),
|
|
47870
|
-
logger:
|
|
48104
|
+
logger: logger34,
|
|
47871
48105
|
resolveBySlug: resolveEnrollmentBySlug,
|
|
47872
48106
|
promptLessonChoice: defaultPromptLessonChoice
|
|
47873
48107
|
};
|