@tostudy-ai/cli 0.11.1 → 0.11.2
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 +104 -52
- package/dist/cli.js.map +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1310,10 +1310,19 @@ function formatProgress(data) {
|
|
|
1310
1310
|
`Li\xE7\xF5es conclu\xEDdas: ${data.completedLessons}`,
|
|
1311
1311
|
`Tempo restante estimado: ~${data.estimatedMinutesRemaining} min`,
|
|
1312
1312
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1313
|
-
""
|
|
1314
|
-
"\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o",
|
|
1315
|
-
"\u2192 tostudy lesson para ver o conte\xFAdo da li\xE7\xE3o atual"
|
|
1313
|
+
""
|
|
1316
1314
|
];
|
|
1315
|
+
if (data.isArchived) {
|
|
1316
|
+
lines.push(
|
|
1317
|
+
"\u26A0 Curso arquivado \u2014 somente leitura.",
|
|
1318
|
+
"\u2192 tostudy lesson para reler o conte\xFAdo j\xE1 estudado"
|
|
1319
|
+
);
|
|
1320
|
+
} else {
|
|
1321
|
+
lines.push(
|
|
1322
|
+
"\u2192 tostudy next para avan\xE7ar para a pr\xF3xima li\xE7\xE3o",
|
|
1323
|
+
"\u2192 tostudy lesson para ver o conte\xFAdo da li\xE7\xE3o atual"
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1317
1326
|
return lines.join("\n");
|
|
1318
1327
|
}
|
|
1319
1328
|
function formatLesson(data) {
|
|
@@ -2323,7 +2332,8 @@ var init_errors_pt_br = __esm({
|
|
|
2323
2332
|
logoutSuccess: "\n Deslogado com sucesso.\n",
|
|
2324
2333
|
workspaceCommandDescription: "Gerenciar workspace de estudo local",
|
|
2325
2334
|
workspaceSetupDescription: "Criar estrutura do workspace para o curso ativo",
|
|
2326
|
-
insufficientCredits: "\u274C Voc\xEA est\xE1 sem cr\xE9ditos. Cada resposta do tutor de IA consome cr\xE9ditos para cobrir o processamento. Recarregue em https://tostudy.ai/student/credits para continuar de onde parou.\n"
|
|
2335
|
+
insufficientCredits: "\u274C Voc\xEA est\xE1 sem cr\xE9ditos. Cada resposta do tutor de IA consome cr\xE9ditos para cobrir o processamento. Recarregue em https://tostudy.ai/student/credits para continuar de onde parou.\n",
|
|
2336
|
+
courseArchived: "Este curso foi arquivado e est\xE1 dispon\xEDvel somente para leitura.\nUse `tostudy lesson` para revisar o conte\xFAdo j\xE1 estudado.\n"
|
|
2327
2337
|
};
|
|
2328
2338
|
}
|
|
2329
2339
|
});
|
|
@@ -2341,7 +2351,8 @@ var init_errors_en_us = __esm({
|
|
|
2341
2351
|
logoutSuccess: "\n Logged out successfully.\n",
|
|
2342
2352
|
workspaceCommandDescription: "Manage local study workspace",
|
|
2343
2353
|
workspaceSetupDescription: "Create the workspace structure for the active course",
|
|
2344
|
-
insufficientCredits: "\u274C You're out of credits. Every reply from the AI tutor uses credits to cover processing. Top up at https://tostudy.ai/student/credits to continue from where you stopped.\n"
|
|
2354
|
+
insufficientCredits: "\u274C You're out of credits. Every reply from the AI tutor uses credits to cover processing. Top up at https://tostudy.ai/student/credits to continue from where you stopped.\n",
|
|
2355
|
+
courseArchived: "This course has been archived and is available for reading only.\nUse `tostudy lesson` to review the content you've already studied.\n"
|
|
2345
2356
|
};
|
|
2346
2357
|
}
|
|
2347
2358
|
});
|
|
@@ -2373,6 +2384,10 @@ function isInsufficientCreditsError(err) {
|
|
|
2373
2384
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2374
2385
|
return msg.includes("INSUFFICIENT_CREDITS");
|
|
2375
2386
|
}
|
|
2387
|
+
function isCourseArchivedError(err) {
|
|
2388
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2389
|
+
return msg.includes("COURSE_ARCHIVED");
|
|
2390
|
+
}
|
|
2376
2391
|
var BUNDLES, _cachedLocale;
|
|
2377
2392
|
var init_errors = __esm({
|
|
2378
2393
|
"src/errors/index.ts"() {
|
|
@@ -2569,7 +2584,7 @@ var CLI_VERSION;
|
|
|
2569
2584
|
var init_version = __esm({
|
|
2570
2585
|
"src/version.ts"() {
|
|
2571
2586
|
"use strict";
|
|
2572
|
-
CLI_VERSION = true ? "0.11.
|
|
2587
|
+
CLI_VERSION = true ? "0.11.2" : "0.7.1";
|
|
2573
2588
|
}
|
|
2574
2589
|
});
|
|
2575
2590
|
|
|
@@ -37113,7 +37128,7 @@ var init_credit_movement_audit_log = __esm({
|
|
|
37113
37128
|
});
|
|
37114
37129
|
|
|
37115
37130
|
// ../../packages/database/src/schema/marketing.ts
|
|
37116
|
-
var testimonialStatusEnum, marketingContentTypeEnum, creatorTestimonials2, marketingContent2, newsletterSubscribers, contactSubmissions;
|
|
37131
|
+
var testimonialStatusEnum, testimonialPlacementEnum, marketingContentTypeEnum, creatorTestimonials2, marketingContent2, newsletterSubscribers, contactSubmissions;
|
|
37117
37132
|
var init_marketing = __esm({
|
|
37118
37133
|
"../../packages/database/src/schema/marketing.ts"() {
|
|
37119
37134
|
"use strict";
|
|
@@ -37124,6 +37139,11 @@ var init_marketing = __esm({
|
|
|
37124
37139
|
"published",
|
|
37125
37140
|
"archived"
|
|
37126
37141
|
]);
|
|
37142
|
+
testimonialPlacementEnum = pgEnum("testimonial_placement", [
|
|
37143
|
+
"homepage",
|
|
37144
|
+
"creators",
|
|
37145
|
+
"both"
|
|
37146
|
+
]);
|
|
37127
37147
|
marketingContentTypeEnum = pgEnum("marketing_content_type", [
|
|
37128
37148
|
"text",
|
|
37129
37149
|
// Simple text content
|
|
@@ -37158,6 +37178,7 @@ var init_marketing = __esm({
|
|
|
37158
37178
|
featured: boolean("featured").default(false).notNull(),
|
|
37159
37179
|
// Show in carousel
|
|
37160
37180
|
displayOrder: integer("display_order").default(0).notNull(),
|
|
37181
|
+
placement: testimonialPlacementEnum("placement").default("creators").notNull(),
|
|
37161
37182
|
// Localization support (null = applies to all locales)
|
|
37162
37183
|
locale: varchar("locale", { length: 10 }),
|
|
37163
37184
|
// Metadata
|
|
@@ -37170,7 +37191,8 @@ var init_marketing = __esm({
|
|
|
37170
37191
|
statusIdx: index("creator_testimonials_status_idx").on(table.status),
|
|
37171
37192
|
featuredIdx: index("creator_testimonials_featured_idx").on(table.featured),
|
|
37172
37193
|
displayOrderIdx: index("creator_testimonials_display_order_idx").on(table.displayOrder),
|
|
37173
|
-
localeIdx: index("creator_testimonials_locale_idx").on(table.locale)
|
|
37194
|
+
localeIdx: index("creator_testimonials_locale_idx").on(table.locale),
|
|
37195
|
+
placementIdx: index("creator_testimonials_placement_idx").on(table.placement)
|
|
37174
37196
|
})
|
|
37175
37197
|
);
|
|
37176
37198
|
marketingContent2 = pgTable(
|
|
@@ -41106,44 +41128,39 @@ var init_course_allowlist = __esm({
|
|
|
41106
41128
|
}
|
|
41107
41129
|
});
|
|
41108
41130
|
|
|
41109
|
-
// ../../node_modules/@parisgroup-ai/pg-backend/dist/idempotency-schema.mjs
|
|
41110
|
-
var pgBackendIdempotencyKeys;
|
|
41111
|
-
var init_idempotency_schema = __esm({
|
|
41112
|
-
"../../node_modules/@parisgroup-ai/pg-backend/dist/idempotency-schema.mjs"() {
|
|
41113
|
-
init_drizzle_orm();
|
|
41114
|
-
init_pg_core();
|
|
41115
|
-
pgBackendIdempotencyKeys = pgTable("pg_backend_idempotency_keys", {
|
|
41116
|
-
reservationId: uuid("reservation_id").primaryKey().defaultRandom(),
|
|
41117
|
-
idempotencyKey: text("idempotency_key").notNull(),
|
|
41118
|
-
resource: text("resource").notNull(),
|
|
41119
|
-
operation: text("operation").notNull(),
|
|
41120
|
-
fingerprint: text("fingerprint").notNull(),
|
|
41121
|
-
scopeKey: text("scope_key"),
|
|
41122
|
-
status: text("status").notNull(),
|
|
41123
|
-
response: jsonb("response"),
|
|
41124
|
-
reservedAt: timestamp("reserved_at", { withTimezone: true }).notNull().defaultNow(),
|
|
41125
|
-
committedAt: timestamp("committed_at", { withTimezone: true }),
|
|
41126
|
-
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull()
|
|
41127
|
-
}, (t) => ({
|
|
41128
|
-
uniqueKey: uniqueIndex("pg_backend_idempotency_unique").on(t.idempotencyKey, t.resource, t.operation, sql`COALESCE(${t.scopeKey}, '')`),
|
|
41129
|
-
expiresIdx: index("pg_backend_idempotency_expires").on(t.expiresAt),
|
|
41130
|
-
pendingIdx: index("pg_backend_idempotency_pending").on(t.status, t.reservedAt)
|
|
41131
|
-
}));
|
|
41132
|
-
}
|
|
41133
|
-
});
|
|
41134
|
-
|
|
41135
|
-
// ../../node_modules/@parisgroup-ai/pg-backend/dist/index.mjs
|
|
41136
|
-
var init_dist2 = __esm({
|
|
41137
|
-
"../../node_modules/@parisgroup-ai/pg-backend/dist/index.mjs"() {
|
|
41138
|
-
init_idempotency_schema();
|
|
41139
|
-
}
|
|
41140
|
-
});
|
|
41141
|
-
|
|
41142
41131
|
// ../../packages/database/src/schema/idempotency.ts
|
|
41132
|
+
var pgBackendIdempotencyKeys;
|
|
41143
41133
|
var init_idempotency = __esm({
|
|
41144
41134
|
"../../packages/database/src/schema/idempotency.ts"() {
|
|
41145
41135
|
"use strict";
|
|
41146
|
-
|
|
41136
|
+
init_drizzle_orm();
|
|
41137
|
+
init_pg_core();
|
|
41138
|
+
pgBackendIdempotencyKeys = pgTable(
|
|
41139
|
+
"pg_backend_idempotency_keys",
|
|
41140
|
+
{
|
|
41141
|
+
reservationId: uuid("reservation_id").primaryKey().defaultRandom(),
|
|
41142
|
+
idempotencyKey: text("idempotency_key").notNull(),
|
|
41143
|
+
resource: text("resource").notNull(),
|
|
41144
|
+
operation: text("operation").notNull(),
|
|
41145
|
+
fingerprint: text("fingerprint").notNull(),
|
|
41146
|
+
scopeKey: text("scope_key"),
|
|
41147
|
+
status: text("status").notNull(),
|
|
41148
|
+
response: jsonb("response"),
|
|
41149
|
+
reservedAt: timestamp("reserved_at", { withTimezone: true }).notNull().defaultNow(),
|
|
41150
|
+
committedAt: timestamp("committed_at", { withTimezone: true }),
|
|
41151
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull()
|
|
41152
|
+
},
|
|
41153
|
+
(t) => [
|
|
41154
|
+
uniqueIndex("pg_backend_idempotency_unique").on(
|
|
41155
|
+
t.idempotencyKey,
|
|
41156
|
+
t.resource,
|
|
41157
|
+
t.operation,
|
|
41158
|
+
sql`COALESCE(${t.scopeKey}, '')`
|
|
41159
|
+
),
|
|
41160
|
+
index("pg_backend_idempotency_expires").on(t.expiresAt),
|
|
41161
|
+
index("pg_backend_idempotency_pending").on(t.status, t.reservedAt)
|
|
41162
|
+
]
|
|
41163
|
+
);
|
|
41147
41164
|
}
|
|
41148
41165
|
});
|
|
41149
41166
|
|
|
@@ -41564,6 +41581,7 @@ __export(schema_exports, {
|
|
|
41564
41581
|
syncLogsRelations: () => syncLogsRelations2,
|
|
41565
41582
|
systemConfigs: () => systemConfigs,
|
|
41566
41583
|
systemConfigsRelations: () => systemConfigsRelations,
|
|
41584
|
+
testimonialPlacementEnum: () => testimonialPlacementEnum,
|
|
41567
41585
|
testimonialStatusEnum: () => testimonialStatusEnum,
|
|
41568
41586
|
threadStatusEnum: () => threadStatusEnum,
|
|
41569
41587
|
toneEnum: () => toneEnum,
|
|
@@ -42061,9 +42079,8 @@ async function runStart(opts, deps = defaultDeps3) {
|
|
|
42061
42079
|
process.stderr.write("Acesse tostudy.ai para estudar este curso pelo ChatStudy.\n");
|
|
42062
42080
|
process.exit(1);
|
|
42063
42081
|
}
|
|
42064
|
-
if (err
|
|
42065
|
-
|
|
42066
|
-
process.stderr.write("Use `tostudy lesson` para revisar o conte\xFAdo j\xE1 estudado.\n");
|
|
42082
|
+
if (isCourseArchivedError(err)) {
|
|
42083
|
+
deps.stderrWrite(getErrors().courseArchived);
|
|
42067
42084
|
process.exit(1);
|
|
42068
42085
|
}
|
|
42069
42086
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -42082,6 +42099,7 @@ var init_start = __esm({
|
|
|
42082
42099
|
init_workspace_state();
|
|
42083
42100
|
init_status();
|
|
42084
42101
|
init_formatter();
|
|
42102
|
+
init_errors();
|
|
42085
42103
|
logger9 = createLogger("cli:start");
|
|
42086
42104
|
defaultDeps3 = {
|
|
42087
42105
|
requireSession,
|
|
@@ -42117,6 +42135,7 @@ var init_start_next = __esm({
|
|
|
42117
42135
|
init_course_state();
|
|
42118
42136
|
init_workspace_state();
|
|
42119
42137
|
init_formatter();
|
|
42138
|
+
init_errors();
|
|
42120
42139
|
logger10 = createLogger("cli:start-next");
|
|
42121
42140
|
startNextCommand = new Command9("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
|
|
42122
42141
|
try {
|
|
@@ -42144,9 +42163,8 @@ var init_start_next = __esm({
|
|
|
42144
42163
|
process.stderr.write("\u2192 tostudy courses para ver outros cursos\n");
|
|
42145
42164
|
process.exit(0);
|
|
42146
42165
|
}
|
|
42147
|
-
if (err
|
|
42148
|
-
process.stderr.write(
|
|
42149
|
-
process.stderr.write("Use `tostudy lesson` para revisar o conte\xFAdo j\xE1 estudado.\n");
|
|
42166
|
+
if (isCourseArchivedError(err)) {
|
|
42167
|
+
process.stderr.write(getErrors().courseArchived);
|
|
42150
42168
|
process.exit(1);
|
|
42151
42169
|
}
|
|
42152
42170
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -42170,6 +42188,7 @@ var init_next = __esm({
|
|
|
42170
42188
|
init_course_state();
|
|
42171
42189
|
init_workspace_state();
|
|
42172
42190
|
init_formatter();
|
|
42191
|
+
init_errors();
|
|
42173
42192
|
logger11 = createLogger("cli:next");
|
|
42174
42193
|
nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
42175
42194
|
try {
|
|
@@ -42195,6 +42214,12 @@ var init_next = __esm({
|
|
|
42195
42214
|
output(formatLesson(lessonData), { json: false });
|
|
42196
42215
|
}
|
|
42197
42216
|
} catch (err) {
|
|
42217
|
+
if (isCourseArchivedError(err)) {
|
|
42218
|
+
const friendly = getErrors().courseArchived;
|
|
42219
|
+
if (opts.json) jsonError("course_archived", { message: friendly });
|
|
42220
|
+
process.stderr.write(friendly);
|
|
42221
|
+
process.exit(1);
|
|
42222
|
+
}
|
|
42198
42223
|
if (err instanceof CliApiError) {
|
|
42199
42224
|
if (err.status === 403 && err.message === "CHANNEL_MISMATCH") {
|
|
42200
42225
|
process.stderr.write("Este curso n\xE3o est\xE1 dispon\xEDvel via CLI.\n");
|
|
@@ -42271,6 +42296,7 @@ var init_lesson = __esm({
|
|
|
42271
42296
|
"use strict";
|
|
42272
42297
|
init_src();
|
|
42273
42298
|
init_lessons2();
|
|
42299
|
+
init_courses();
|
|
42274
42300
|
init_http();
|
|
42275
42301
|
init_guards();
|
|
42276
42302
|
init_course_state();
|
|
@@ -42278,7 +42304,10 @@ var init_lesson = __esm({
|
|
|
42278
42304
|
init_resolve();
|
|
42279
42305
|
init_errors();
|
|
42280
42306
|
logger12 = createLogger("cli:lesson");
|
|
42281
|
-
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").
|
|
42307
|
+
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").option(
|
|
42308
|
+
"--read <lessonId>",
|
|
42309
|
+
"Read a specific lesson by id (works on archived / read-only courses)"
|
|
42310
|
+
).action(async (opts) => {
|
|
42282
42311
|
try {
|
|
42283
42312
|
const session = await requireSession();
|
|
42284
42313
|
const activeCourse = await requireActiveCourse();
|
|
@@ -42286,10 +42315,21 @@ var init_lesson = __esm({
|
|
|
42286
42315
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
42287
42316
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
42288
42317
|
const deps = { data, logger: logger12 };
|
|
42289
|
-
|
|
42318
|
+
let lessonId = opts.read ?? activeCourse.currentLessonId;
|
|
42290
42319
|
if (!lessonId) {
|
|
42291
|
-
|
|
42292
|
-
|
|
42320
|
+
try {
|
|
42321
|
+
const prog = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
42322
|
+
lessonId = prog.currentLesson?.id || void 0;
|
|
42323
|
+
if (prog.isArchived) {
|
|
42324
|
+
process.stderr.write("\u2139 Curso arquivado \u2014 modo leitura.\n");
|
|
42325
|
+
}
|
|
42326
|
+
} catch {
|
|
42327
|
+
}
|
|
42328
|
+
}
|
|
42329
|
+
if (!lessonId) {
|
|
42330
|
+
if (opts.json)
|
|
42331
|
+
jsonError("no_active_lesson", { message: "Nenhuma li\xE7\xE3o encontrada para leitura" });
|
|
42332
|
+
error("Nenhuma li\xE7\xE3o encontrada para leitura. Rode: tostudy start ou tostudy next");
|
|
42293
42333
|
}
|
|
42294
42334
|
const content = await getContent({ lessonId, enrollmentId: activeCourse.enrollmentId }, deps);
|
|
42295
42335
|
if (opts.json) {
|
|
@@ -42356,6 +42396,12 @@ var init_hint = __esm({
|
|
|
42356
42396
|
output(formatHint(hint), { json: false });
|
|
42357
42397
|
}
|
|
42358
42398
|
} catch (err) {
|
|
42399
|
+
if (isCourseArchivedError(err)) {
|
|
42400
|
+
const friendly = getErrors().courseArchived;
|
|
42401
|
+
if (opts.json) jsonError("course_archived", { message: friendly });
|
|
42402
|
+
error(friendly);
|
|
42403
|
+
return;
|
|
42404
|
+
}
|
|
42359
42405
|
if (isInsufficientCreditsError(err)) {
|
|
42360
42406
|
const friendly = getErrors().insufficientCredits;
|
|
42361
42407
|
if (opts.json) jsonError("insufficient_credits", { message: friendly });
|
|
@@ -42780,6 +42826,12 @@ var init_validate = __esm({
|
|
|
42780
42826
|
}
|
|
42781
42827
|
process.exit(result.passed ? 0 : 1);
|
|
42782
42828
|
} catch (err) {
|
|
42829
|
+
if (isCourseArchivedError(err)) {
|
|
42830
|
+
const friendly = getErrors().courseArchived;
|
|
42831
|
+
if (opts.json) jsonError("course_archived", { message: friendly });
|
|
42832
|
+
error(friendly);
|
|
42833
|
+
return;
|
|
42834
|
+
}
|
|
42783
42835
|
if (isInsufficientCreditsError(err)) {
|
|
42784
42836
|
const friendly = getErrors().insufficientCredits;
|
|
42785
42837
|
if (opts.json) jsonError("insufficient_credits", { message: friendly });
|