@tostudy-ai/cli 0.16.10 → 0.16.11
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 +180 -181
- package/dist/cli.js.map +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2829,18 +2829,6 @@ var init_errors_en_us = __esm({
|
|
|
2829
2829
|
});
|
|
2830
2830
|
|
|
2831
2831
|
// src/errors/index.ts
|
|
2832
|
-
import fs6 from "node:fs";
|
|
2833
|
-
import path7 from "node:path";
|
|
2834
|
-
function readStoredLocale() {
|
|
2835
|
-
try {
|
|
2836
|
-
const p = path7.join(getConfigDir(), "config.json");
|
|
2837
|
-
if (!fs6.existsSync(p)) return null;
|
|
2838
|
-
const { locale } = JSON.parse(fs6.readFileSync(p, "utf-8"));
|
|
2839
|
-
return locale === "pt-BR" || locale === "en-US" ? locale : null;
|
|
2840
|
-
} catch {
|
|
2841
|
-
return null;
|
|
2842
|
-
}
|
|
2843
|
-
}
|
|
2844
2832
|
function resolveLocale() {
|
|
2845
2833
|
if (_cachedLocale !== null) return _cachedLocale;
|
|
2846
2834
|
const argv = process.argv;
|
|
@@ -2852,8 +2840,8 @@ function resolveLocale() {
|
|
|
2852
2840
|
return val;
|
|
2853
2841
|
}
|
|
2854
2842
|
}
|
|
2855
|
-
const stored =
|
|
2856
|
-
if (stored) {
|
|
2843
|
+
const stored = process.env["TOSTUDY_LOCALE"];
|
|
2844
|
+
if (stored === "pt-BR" || stored === "en-US") {
|
|
2857
2845
|
_cachedLocale = stored;
|
|
2858
2846
|
return stored;
|
|
2859
2847
|
}
|
|
@@ -2888,7 +2876,6 @@ var BUNDLES, _cachedLocale;
|
|
|
2888
2876
|
var init_errors = __esm({
|
|
2889
2877
|
"src/errors/index.ts"() {
|
|
2890
2878
|
"use strict";
|
|
2891
|
-
init_config_dir();
|
|
2892
2879
|
init_errors_pt_br();
|
|
2893
2880
|
init_errors_en_us();
|
|
2894
2881
|
BUNDLES = {
|
|
@@ -2902,12 +2889,12 @@ var init_errors = __esm({
|
|
|
2902
2889
|
// src/workspace/workspace-marker.ts
|
|
2903
2890
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
2904
2891
|
import os4 from "node:os";
|
|
2905
|
-
import
|
|
2892
|
+
import path7 from "node:path";
|
|
2906
2893
|
function resolveMarkerPath(workspacePath) {
|
|
2907
|
-
if (
|
|
2908
|
-
return
|
|
2894
|
+
if (path7.basename(workspacePath) === ".tostudy") {
|
|
2895
|
+
return path7.join(workspacePath, "workspace.json");
|
|
2909
2896
|
}
|
|
2910
|
-
return
|
|
2897
|
+
return path7.join(workspacePath, ".tostudy", "workspace.json");
|
|
2911
2898
|
}
|
|
2912
2899
|
async function readWorkspaceMarker(workspacePath) {
|
|
2913
2900
|
const filePath = resolveMarkerPath(workspacePath);
|
|
@@ -2925,13 +2912,13 @@ async function readWorkspaceMarker(workspacePath) {
|
|
|
2925
2912
|
}
|
|
2926
2913
|
}
|
|
2927
2914
|
async function writeWorkspaceMarker(workspacePath, input2, options = {}) {
|
|
2928
|
-
const homeDir =
|
|
2929
|
-
const resolvedWorkspace =
|
|
2930
|
-
if (resolvedWorkspace === homeDir || homeDir.startsWith(resolvedWorkspace +
|
|
2915
|
+
const homeDir = path7.resolve(options.homeDir ?? os4.homedir());
|
|
2916
|
+
const resolvedWorkspace = path7.resolve(workspacePath);
|
|
2917
|
+
if (resolvedWorkspace === homeDir || homeDir.startsWith(resolvedWorkspace + path7.sep)) {
|
|
2931
2918
|
throw new Error(getErrors().workspaceRefusedAtHome);
|
|
2932
2919
|
}
|
|
2933
2920
|
const filePath = resolveMarkerPath(workspacePath);
|
|
2934
|
-
const dir =
|
|
2921
|
+
const dir = path7.dirname(filePath);
|
|
2935
2922
|
if (!existsSync3(dir)) {
|
|
2936
2923
|
mkdirSync3(dir, { recursive: true });
|
|
2937
2924
|
}
|
|
@@ -2968,7 +2955,7 @@ __export(workspace_state_exports, {
|
|
|
2968
2955
|
});
|
|
2969
2956
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2970
2957
|
import os5 from "node:os";
|
|
2971
|
-
import
|
|
2958
|
+
import path8 from "node:path";
|
|
2972
2959
|
async function readWorkspaceState(workspacePath) {
|
|
2973
2960
|
const marker = await readWorkspaceMarker(workspacePath);
|
|
2974
2961
|
if (!marker) return null;
|
|
@@ -2997,13 +2984,13 @@ async function readWorkspaceState(workspacePath) {
|
|
|
2997
2984
|
}
|
|
2998
2985
|
}
|
|
2999
2986
|
async function findWorkspaceState(startCwd = process.cwd(), homeDir = os5.homedir()) {
|
|
3000
|
-
const home =
|
|
3001
|
-
let current =
|
|
2987
|
+
const home = path8.resolve(homeDir);
|
|
2988
|
+
let current = path8.resolve(startCwd);
|
|
3002
2989
|
while (true) {
|
|
3003
2990
|
if (current === home) return null;
|
|
3004
2991
|
const state = await readWorkspaceState(current);
|
|
3005
2992
|
if (state) return { state, workspacePath: current };
|
|
3006
|
-
const parent =
|
|
2993
|
+
const parent = path8.dirname(current);
|
|
3007
2994
|
if (parent === current) return null;
|
|
3008
2995
|
current = parent;
|
|
3009
2996
|
}
|
|
@@ -3072,7 +3059,7 @@ __export(course_state_exports, {
|
|
|
3072
3059
|
setCourseWorkspacePath: () => setCourseWorkspacePath,
|
|
3073
3060
|
setLastInitCourseId: () => setLastInitCourseId
|
|
3074
3061
|
});
|
|
3075
|
-
import
|
|
3062
|
+
import fs6 from "node:fs";
|
|
3076
3063
|
async function getCourseOnboardingState(courseId, configDir) {
|
|
3077
3064
|
const state = readCourseOnboardingState(configDir);
|
|
3078
3065
|
return state[courseId] ?? null;
|
|
@@ -3094,7 +3081,7 @@ async function saveCourseLearnerProfile(course, learnerProfile, artifacts, confi
|
|
|
3094
3081
|
}
|
|
3095
3082
|
async function clearAllCourseOnboarding(configDir) {
|
|
3096
3083
|
const onboardingPath = getCourseOnboardingPath(configDir);
|
|
3097
|
-
if (
|
|
3084
|
+
if (fs6.existsSync(onboardingPath)) fs6.unlinkSync(onboardingPath);
|
|
3098
3085
|
}
|
|
3099
3086
|
var init_course_state = __esm({
|
|
3100
3087
|
"src/onboarding/course-state.ts"() {
|
|
@@ -3137,14 +3124,14 @@ __export(resolve_exports, {
|
|
|
3137
3124
|
resolveVaultPath: () => resolveVaultPath,
|
|
3138
3125
|
resolveWorkspace: () => resolveWorkspace
|
|
3139
3126
|
});
|
|
3140
|
-
import
|
|
3141
|
-
import
|
|
3127
|
+
import fs7 from "node:fs/promises";
|
|
3128
|
+
import path9 from "node:path";
|
|
3142
3129
|
import os6 from "node:os";
|
|
3143
3130
|
async function resolveWorkspace(courseTitle, basePath = DEFAULT_BASE) {
|
|
3144
3131
|
const slug = courseSlug(courseTitle);
|
|
3145
|
-
const candidate =
|
|
3132
|
+
const candidate = path9.join(basePath, slug);
|
|
3146
3133
|
try {
|
|
3147
|
-
await
|
|
3134
|
+
await fs7.access(path9.join(candidate, ".ana-config.json"));
|
|
3148
3135
|
return { found: true, workspacePath: candidate, source: "default" };
|
|
3149
3136
|
} catch {
|
|
3150
3137
|
return { found: false, workspacePath: null };
|
|
@@ -3154,49 +3141,49 @@ async function isCwdWorkspace(cwd = process.cwd()) {
|
|
|
3154
3141
|
return await resolveCwdWorkspacePath(cwd) !== null;
|
|
3155
3142
|
}
|
|
3156
3143
|
async function resolveCwdWorkspacePath(cwd = process.cwd()) {
|
|
3157
|
-
const tostudyDir =
|
|
3144
|
+
const tostudyDir = path9.join(cwd, ".tostudy");
|
|
3158
3145
|
try {
|
|
3159
|
-
const stat = await
|
|
3146
|
+
const stat = await fs7.stat(tostudyDir);
|
|
3160
3147
|
if (stat.isDirectory()) return tostudyDir;
|
|
3161
3148
|
} catch {
|
|
3162
3149
|
}
|
|
3163
3150
|
try {
|
|
3164
|
-
await
|
|
3151
|
+
await fs7.access(path9.join(cwd, ".ana-config.json"));
|
|
3165
3152
|
return cwd;
|
|
3166
3153
|
} catch {
|
|
3167
3154
|
return null;
|
|
3168
3155
|
}
|
|
3169
3156
|
}
|
|
3170
3157
|
async function findCwdWorkspaceUpwards(startCwd = process.cwd(), homeDir = os6.homedir()) {
|
|
3171
|
-
const home =
|
|
3172
|
-
let current =
|
|
3158
|
+
const home = path9.resolve(homeDir);
|
|
3159
|
+
let current = path9.resolve(startCwd);
|
|
3173
3160
|
while (true) {
|
|
3174
3161
|
if (current === home) return null;
|
|
3175
3162
|
const direct = await resolveCwdWorkspacePath(current);
|
|
3176
3163
|
if (direct) return direct;
|
|
3177
|
-
const parent =
|
|
3164
|
+
const parent = path9.dirname(current);
|
|
3178
3165
|
if (parent === current) return null;
|
|
3179
3166
|
current = parent;
|
|
3180
3167
|
}
|
|
3181
3168
|
}
|
|
3182
3169
|
function resolveVaultPath(workspacePath, slug) {
|
|
3183
|
-
const base =
|
|
3184
|
-
return
|
|
3170
|
+
const base = path9.basename(workspacePath) === ".tostudy" ? path9.dirname(workspacePath) : workspacePath;
|
|
3171
|
+
return path9.join(base, `vault-${slug}`);
|
|
3185
3172
|
}
|
|
3186
3173
|
function cliWorkspacePaths(workspacePath, courseTitle) {
|
|
3187
|
-
const base =
|
|
3174
|
+
const base = path9.basename(workspacePath) === ".tostudy" ? path9.dirname(workspacePath) : workspacePath;
|
|
3188
3175
|
return { workspace: base, vault: resolveVaultPath(workspacePath, courseSlug(courseTitle)) };
|
|
3189
3176
|
}
|
|
3190
3177
|
async function findExistingVault(workspacePath, slug) {
|
|
3191
3178
|
const slugged = resolveVaultPath(workspacePath, slug);
|
|
3192
3179
|
try {
|
|
3193
|
-
await
|
|
3180
|
+
await fs7.access(path9.join(slugged, ".ana-vault.json"));
|
|
3194
3181
|
return slugged;
|
|
3195
3182
|
} catch {
|
|
3196
3183
|
}
|
|
3197
|
-
const legacy =
|
|
3184
|
+
const legacy = path9.join(workspacePath, "vault");
|
|
3198
3185
|
try {
|
|
3199
|
-
await
|
|
3186
|
+
await fs7.access(path9.join(legacy, ".ana-vault.json"));
|
|
3200
3187
|
return legacy;
|
|
3201
3188
|
} catch {
|
|
3202
3189
|
return null;
|
|
@@ -3209,7 +3196,7 @@ async function resolveEffectiveWorkspace(courseTitle, storedPath, cwd = process.
|
|
|
3209
3196
|
}
|
|
3210
3197
|
if (storedPath) {
|
|
3211
3198
|
try {
|
|
3212
|
-
await
|
|
3199
|
+
await fs7.access(path9.join(storedPath, ".ana-config.json"));
|
|
3213
3200
|
return { found: true, workspacePath: storedPath, source: "stored" };
|
|
3214
3201
|
} catch {
|
|
3215
3202
|
}
|
|
@@ -3230,7 +3217,7 @@ var init_resolve = __esm({
|
|
|
3230
3217
|
"src/workspace/resolve.ts"() {
|
|
3231
3218
|
"use strict";
|
|
3232
3219
|
init_slug();
|
|
3233
|
-
DEFAULT_BASE =
|
|
3220
|
+
DEFAULT_BASE = path9.join(os6.homedir(), "study");
|
|
3234
3221
|
courseSlug = slugify;
|
|
3235
3222
|
resolveActiveCourseWithOverride = resolveActiveCourseFromWorkspace;
|
|
3236
3223
|
}
|
|
@@ -3426,7 +3413,7 @@ var CLI_VERSION;
|
|
|
3426
3413
|
var init_version = __esm({
|
|
3427
3414
|
"src/version.ts"() {
|
|
3428
3415
|
"use strict";
|
|
3429
|
-
CLI_VERSION = true ? "0.16.
|
|
3416
|
+
CLI_VERSION = true ? "0.16.11" : "0.7.1";
|
|
3430
3417
|
}
|
|
3431
3418
|
});
|
|
3432
3419
|
|
|
@@ -3440,13 +3427,13 @@ __export(update_checker_exports, {
|
|
|
3440
3427
|
readCache: () => readCache,
|
|
3441
3428
|
writeCache: () => writeCache
|
|
3442
3429
|
});
|
|
3443
|
-
import
|
|
3444
|
-
import
|
|
3430
|
+
import fs8 from "node:fs";
|
|
3431
|
+
import path10 from "node:path";
|
|
3445
3432
|
function readCache(configDir) {
|
|
3446
3433
|
try {
|
|
3447
|
-
const p =
|
|
3448
|
-
if (!
|
|
3449
|
-
return JSON.parse(
|
|
3434
|
+
const p = path10.join(configDir ?? getConfigDir(), CACHE_FILE);
|
|
3435
|
+
if (!fs8.existsSync(p)) return null;
|
|
3436
|
+
return JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
3450
3437
|
} catch {
|
|
3451
3438
|
return null;
|
|
3452
3439
|
}
|
|
@@ -3454,8 +3441,8 @@ function readCache(configDir) {
|
|
|
3454
3441
|
function writeCache(cache, configDir) {
|
|
3455
3442
|
try {
|
|
3456
3443
|
const dir = configDir ?? getConfigDir();
|
|
3457
|
-
|
|
3458
|
-
|
|
3444
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
3445
|
+
fs8.writeFileSync(path10.join(dir, CACHE_FILE), JSON.stringify(cache));
|
|
3459
3446
|
} catch {
|
|
3460
3447
|
}
|
|
3461
3448
|
}
|
|
@@ -3525,17 +3512,17 @@ var init_update_checker = __esm({
|
|
|
3525
3512
|
});
|
|
3526
3513
|
|
|
3527
3514
|
// src/learner-brief/cache.ts
|
|
3528
|
-
import
|
|
3529
|
-
import
|
|
3515
|
+
import fs9 from "node:fs";
|
|
3516
|
+
import path11 from "node:path";
|
|
3530
3517
|
function resolveCachePath(configDir) {
|
|
3531
|
-
return
|
|
3518
|
+
return path11.join(configDir, "student-brief.json");
|
|
3532
3519
|
}
|
|
3533
3520
|
async function readBriefCache(configDir) {
|
|
3534
3521
|
const dir = configDir ?? getConfigDir();
|
|
3535
3522
|
const p = resolveCachePath(dir);
|
|
3536
|
-
if (!
|
|
3523
|
+
if (!fs9.existsSync(p)) return null;
|
|
3537
3524
|
try {
|
|
3538
|
-
const raw =
|
|
3525
|
+
const raw = fs9.readFileSync(p, "utf-8");
|
|
3539
3526
|
return JSON.parse(raw);
|
|
3540
3527
|
} catch {
|
|
3541
3528
|
return null;
|
|
@@ -3543,8 +3530,8 @@ async function readBriefCache(configDir) {
|
|
|
3543
3530
|
}
|
|
3544
3531
|
async function writeBriefCache(configDir, cache) {
|
|
3545
3532
|
const dir = configDir ?? getConfigDir();
|
|
3546
|
-
|
|
3547
|
-
|
|
3533
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
3534
|
+
fs9.writeFileSync(resolveCachePath(dir), JSON.stringify(cache, null, 2), { mode: 384 });
|
|
3548
3535
|
}
|
|
3549
3536
|
var init_cache = __esm({
|
|
3550
3537
|
"src/learner-brief/cache.ts"() {
|
|
@@ -3554,23 +3541,23 @@ var init_cache = __esm({
|
|
|
3554
3541
|
});
|
|
3555
3542
|
|
|
3556
3543
|
// src/tutor-persona/cache.ts
|
|
3557
|
-
import
|
|
3558
|
-
import
|
|
3544
|
+
import fs10 from "node:fs";
|
|
3545
|
+
import path12 from "node:path";
|
|
3559
3546
|
function resolveCachePath2(configDir) {
|
|
3560
|
-
return
|
|
3547
|
+
return path12.join(configDir, "tutor-personalities.json");
|
|
3561
3548
|
}
|
|
3562
3549
|
function readAll(configDir) {
|
|
3563
3550
|
const p = resolveCachePath2(configDir);
|
|
3564
|
-
if (!
|
|
3551
|
+
if (!fs10.existsSync(p)) return {};
|
|
3565
3552
|
try {
|
|
3566
|
-
return JSON.parse(
|
|
3553
|
+
return JSON.parse(fs10.readFileSync(p, "utf-8"));
|
|
3567
3554
|
} catch {
|
|
3568
3555
|
return {};
|
|
3569
3556
|
}
|
|
3570
3557
|
}
|
|
3571
3558
|
function writeAll(configDir, cache) {
|
|
3572
|
-
|
|
3573
|
-
|
|
3559
|
+
fs10.mkdirSync(configDir, { recursive: true });
|
|
3560
|
+
fs10.writeFileSync(resolveCachePath2(configDir), JSON.stringify(cache, null, 2), { mode: 384 });
|
|
3574
3561
|
}
|
|
3575
3562
|
async function readPersonaCacheForCourse(configDir, courseId) {
|
|
3576
3563
|
const dir = configDir ?? getConfigDir();
|
|
@@ -4813,7 +4800,7 @@ var init_next = __esm({
|
|
|
4813
4800
|
|
|
4814
4801
|
// src/commands/lesson.ts
|
|
4815
4802
|
import { Command as Command11 } from "commander";
|
|
4816
|
-
import
|
|
4803
|
+
import path13 from "node:path";
|
|
4817
4804
|
function adjustTimeEstimate(type, baseMinutes) {
|
|
4818
4805
|
if (type === "exercise") return Math.max(baseMinutes, 30);
|
|
4819
4806
|
return baseMinutes;
|
|
@@ -4826,7 +4813,7 @@ function formatLessonContent(data, workspacePath, courseTitle) {
|
|
|
4826
4813
|
const isPractical = data.type === "exercise" || isCheckpoint(data.title);
|
|
4827
4814
|
const lines = [`\u2501\u2501\u2501 Li\xE7\xE3o: ${data.title} \u2501\u2501\u2501`];
|
|
4828
4815
|
if (isPractical && workspacePath) {
|
|
4829
|
-
const base =
|
|
4816
|
+
const base = path13.basename(workspacePath) === ".tostudy" ? path13.dirname(workspacePath) : workspacePath;
|
|
4830
4817
|
const slug = courseSlug(courseTitle);
|
|
4831
4818
|
const vaultPath = resolveVaultPath(workspacePath, slug);
|
|
4832
4819
|
lines.push(
|
|
@@ -5370,10 +5357,10 @@ function mergeDefs(...defs) {
|
|
|
5370
5357
|
function cloneDef(schema) {
|
|
5371
5358
|
return mergeDefs(schema._zod.def);
|
|
5372
5359
|
}
|
|
5373
|
-
function getElementAtPath(obj,
|
|
5374
|
-
if (!
|
|
5360
|
+
function getElementAtPath(obj, path24) {
|
|
5361
|
+
if (!path24)
|
|
5375
5362
|
return obj;
|
|
5376
|
-
return
|
|
5363
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
5377
5364
|
}
|
|
5378
5365
|
function promiseAllObject(promisesObj) {
|
|
5379
5366
|
const keys = Object.keys(promisesObj);
|
|
@@ -5685,11 +5672,11 @@ function aborted(x, startIndex = 0) {
|
|
|
5685
5672
|
}
|
|
5686
5673
|
return false;
|
|
5687
5674
|
}
|
|
5688
|
-
function prefixIssues(
|
|
5675
|
+
function prefixIssues(path24, issues) {
|
|
5689
5676
|
return issues.map((iss) => {
|
|
5690
5677
|
var _a2;
|
|
5691
5678
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
5692
|
-
iss.path.unshift(
|
|
5679
|
+
iss.path.unshift(path24);
|
|
5693
5680
|
return iss;
|
|
5694
5681
|
});
|
|
5695
5682
|
}
|
|
@@ -5931,7 +5918,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
|
|
|
5931
5918
|
}
|
|
5932
5919
|
function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
5933
5920
|
const result = { errors: [] };
|
|
5934
|
-
const processError = (error50,
|
|
5921
|
+
const processError = (error50, path24 = []) => {
|
|
5935
5922
|
var _a2, _b;
|
|
5936
5923
|
for (const issue2 of error50.issues) {
|
|
5937
5924
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -5941,7 +5928,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
5941
5928
|
} else if (issue2.code === "invalid_element") {
|
|
5942
5929
|
processError({ issues: issue2.issues }, issue2.path);
|
|
5943
5930
|
} else {
|
|
5944
|
-
const fullpath = [...
|
|
5931
|
+
const fullpath = [...path24, ...issue2.path];
|
|
5945
5932
|
if (fullpath.length === 0) {
|
|
5946
5933
|
result.errors.push(mapper(issue2));
|
|
5947
5934
|
continue;
|
|
@@ -5973,8 +5960,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
5973
5960
|
}
|
|
5974
5961
|
function toDotPath(_path) {
|
|
5975
5962
|
const segs = [];
|
|
5976
|
-
const
|
|
5977
|
-
for (const seg of
|
|
5963
|
+
const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
5964
|
+
for (const seg of path24) {
|
|
5978
5965
|
if (typeof seg === "number")
|
|
5979
5966
|
segs.push(`[${seg}]`);
|
|
5980
5967
|
else if (typeof seg === "symbol")
|
|
@@ -18668,13 +18655,13 @@ function resolveRef(ref, ctx) {
|
|
|
18668
18655
|
if (!ref.startsWith("#")) {
|
|
18669
18656
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
18670
18657
|
}
|
|
18671
|
-
const
|
|
18672
|
-
if (
|
|
18658
|
+
const path24 = ref.slice(1).split("/").filter(Boolean);
|
|
18659
|
+
if (path24.length === 0) {
|
|
18673
18660
|
return ctx.rootSchema;
|
|
18674
18661
|
}
|
|
18675
18662
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
18676
|
-
if (
|
|
18677
|
-
const key =
|
|
18663
|
+
if (path24[0] === defsKey) {
|
|
18664
|
+
const key = path24[1];
|
|
18678
18665
|
if (!key || !ctx.defs[key]) {
|
|
18679
18666
|
throw new Error(`Reference not found: ${ref}`);
|
|
18680
18667
|
}
|
|
@@ -20006,8 +19993,8 @@ var init_init_template = __esm({
|
|
|
20006
19993
|
});
|
|
20007
19994
|
|
|
20008
19995
|
// src/commands/validate.ts
|
|
20009
|
-
import
|
|
20010
|
-
import
|
|
19996
|
+
import fs11 from "node:fs";
|
|
19997
|
+
import path14 from "node:path";
|
|
20011
19998
|
import { Command as Command14 } from "commander";
|
|
20012
19999
|
var logger16, validateCommand;
|
|
20013
20000
|
var init_validate = __esm({
|
|
@@ -20051,21 +20038,21 @@ var init_validate = __esm({
|
|
|
20051
20038
|
}
|
|
20052
20039
|
let solution;
|
|
20053
20040
|
if (opts.stdin) {
|
|
20054
|
-
solution =
|
|
20041
|
+
solution = fs11.readFileSync("/dev/stdin", "utf-8");
|
|
20055
20042
|
} else if (file2) {
|
|
20056
|
-
if (!
|
|
20043
|
+
if (!fs11.existsSync(file2)) {
|
|
20057
20044
|
if (opts.json)
|
|
20058
20045
|
jsonError("file_not_found", { message: `Arquivo n\xE3o encontrado: ${file2}` });
|
|
20059
20046
|
error(`Arquivo n\xE3o encontrado: ${file2}`);
|
|
20060
20047
|
}
|
|
20061
|
-
solution =
|
|
20048
|
+
solution = fs11.readFileSync(file2, "utf-8");
|
|
20062
20049
|
} else {
|
|
20063
20050
|
if (opts.json)
|
|
20064
20051
|
jsonError("no_solution_provided", { message: "Forne\xE7a um arquivo ou use --stdin" });
|
|
20065
20052
|
error("Forne\xE7a um arquivo ou use --stdin.\n\nExemplo: tostudy validate resposta.md");
|
|
20066
20053
|
}
|
|
20067
20054
|
if (file2 && activeCourse.courseTags?.length) {
|
|
20068
|
-
const ext =
|
|
20055
|
+
const ext = path14.extname(file2).toLowerCase();
|
|
20069
20056
|
const LANG_EXTENSIONS = {
|
|
20070
20057
|
".html": ["html", "html5"],
|
|
20071
20058
|
".css": ["css"],
|
|
@@ -20533,14 +20520,14 @@ var init_init = __esm({
|
|
|
20533
20520
|
});
|
|
20534
20521
|
|
|
20535
20522
|
// ../../packages/tostudy-core/src/workspace/setup-workspace.ts
|
|
20536
|
-
import
|
|
20537
|
-
import
|
|
20523
|
+
import fs12 from "node:fs/promises";
|
|
20524
|
+
import path15 from "node:path";
|
|
20538
20525
|
async function setupWorkspace(input2) {
|
|
20539
|
-
const workspacePath =
|
|
20526
|
+
const workspacePath = path15.join(input2.basePath, input2.courseSlug);
|
|
20540
20527
|
for (const dir of WORKSPACE_DIRS) {
|
|
20541
|
-
await
|
|
20528
|
+
await fs12.mkdir(path15.join(workspacePath, dir), { recursive: true });
|
|
20542
20529
|
}
|
|
20543
|
-
const configPath =
|
|
20530
|
+
const configPath = path15.join(workspacePath, ".ana-config.json");
|
|
20544
20531
|
const config2 = {
|
|
20545
20532
|
courseId: input2.courseId,
|
|
20546
20533
|
courseSlug: input2.courseSlug,
|
|
@@ -20550,7 +20537,7 @@ async function setupWorkspace(input2) {
|
|
|
20550
20537
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20551
20538
|
lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20552
20539
|
};
|
|
20553
|
-
await
|
|
20540
|
+
await fs12.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
|
|
20554
20541
|
const readme = [
|
|
20555
20542
|
`# ${input2.courseName}`,
|
|
20556
20543
|
"",
|
|
@@ -20575,7 +20562,7 @@ async function setupWorkspace(input2) {
|
|
|
20575
20562
|
"tostudy vault sync # Sincronizar progresso",
|
|
20576
20563
|
"```"
|
|
20577
20564
|
].join("\n");
|
|
20578
|
-
await
|
|
20565
|
+
await fs12.writeFile(path15.join(workspacePath, "README.md"), readme, "utf-8");
|
|
20579
20566
|
return { workspacePath, directories: WORKSPACE_DIRS, configPath };
|
|
20580
20567
|
}
|
|
20581
20568
|
var WORKSPACE_DIRS;
|
|
@@ -20676,8 +20663,8 @@ var init_templates = __esm({
|
|
|
20676
20663
|
});
|
|
20677
20664
|
|
|
20678
20665
|
// ../../packages/tostudy-core/src/workspace/extract-exercise.ts
|
|
20679
|
-
import
|
|
20680
|
-
import
|
|
20666
|
+
import fs13 from "node:fs/promises";
|
|
20667
|
+
import path16 from "node:path";
|
|
20681
20668
|
function padOrder(n) {
|
|
20682
20669
|
return String(n).padStart(2, "0");
|
|
20683
20670
|
}
|
|
@@ -20703,16 +20690,16 @@ async function extractExercise(input2) {
|
|
|
20703
20690
|
const lessonData = resolveWorkspaceTokens(input2.lessonData, paths);
|
|
20704
20691
|
const moduleDir = `${padOrder(lessonData.moduleOrder)}-${lessonData.moduleSlug}`;
|
|
20705
20692
|
const lessonDir = `${padOrder(lessonData.lessonOrder)}-${lessonData.lessonSlug}`;
|
|
20706
|
-
const exercisePath =
|
|
20707
|
-
await
|
|
20693
|
+
const exercisePath = path16.join(workspacePath, "exercises", moduleDir, lessonDir);
|
|
20694
|
+
await fs13.mkdir(exercisePath, { recursive: true });
|
|
20708
20695
|
const extractedFiles = [];
|
|
20709
20696
|
let hasStarterCode = false;
|
|
20710
20697
|
if (lessonData.sandpackConfig?.files) {
|
|
20711
20698
|
for (const [filePath, fileData] of Object.entries(lessonData.sandpackConfig.files)) {
|
|
20712
20699
|
const cleanPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
20713
|
-
const fullPath =
|
|
20714
|
-
await
|
|
20715
|
-
await
|
|
20700
|
+
const fullPath = path16.join(exercisePath, cleanPath);
|
|
20701
|
+
await fs13.mkdir(path16.dirname(fullPath), { recursive: true });
|
|
20702
|
+
await fs13.writeFile(fullPath, fileData.code, "utf-8");
|
|
20716
20703
|
extractedFiles.push(cleanPath);
|
|
20717
20704
|
hasStarterCode = true;
|
|
20718
20705
|
}
|
|
@@ -20720,13 +20707,13 @@ async function extractExercise(input2) {
|
|
|
20720
20707
|
const tierData = getTierData(lessonData.structuredData, exerciseTier);
|
|
20721
20708
|
const tierCode = tierData?.code;
|
|
20722
20709
|
if (tierCode) {
|
|
20723
|
-
await
|
|
20710
|
+
await fs13.writeFile(path16.join(exercisePath, "exercise.js"), tierCode, "utf-8");
|
|
20724
20711
|
extractedFiles.push("exercise.js");
|
|
20725
20712
|
hasStarterCode = true;
|
|
20726
20713
|
} else {
|
|
20727
20714
|
const starter = getStarterCode(lessonData.structuredData);
|
|
20728
20715
|
if (starter) {
|
|
20729
|
-
await
|
|
20716
|
+
await fs13.writeFile(path16.join(exercisePath, "exercise.js"), starter, "utf-8");
|
|
20730
20717
|
extractedFiles.push("exercise.js");
|
|
20731
20718
|
hasStarterCode = true;
|
|
20732
20719
|
}
|
|
@@ -20744,8 +20731,8 @@ async function extractExercise(input2) {
|
|
|
20744
20731
|
...exerciseDeps
|
|
20745
20732
|
}
|
|
20746
20733
|
};
|
|
20747
|
-
await
|
|
20748
|
-
|
|
20734
|
+
await fs13.writeFile(
|
|
20735
|
+
path16.join(exercisePath, "package.json"),
|
|
20749
20736
|
JSON.stringify(pkgJson, null, 2),
|
|
20750
20737
|
"utf-8"
|
|
20751
20738
|
);
|
|
@@ -20757,20 +20744,20 @@ async function extractExercise(input2) {
|
|
|
20757
20744
|
);
|
|
20758
20745
|
for (const [configFile, configContent] of Object.entries(scaffold.configs)) {
|
|
20759
20746
|
if (!sandpackFileNames.has(configFile)) {
|
|
20760
|
-
await
|
|
20747
|
+
await fs13.writeFile(path16.join(exercisePath, configFile), configContent, "utf-8");
|
|
20761
20748
|
extractedFiles.push(configFile);
|
|
20762
20749
|
}
|
|
20763
20750
|
}
|
|
20764
20751
|
const setupSh = `#!/bin/sh
|
|
20765
20752
|
${scaffold.setupScript}
|
|
20766
20753
|
`;
|
|
20767
|
-
await
|
|
20754
|
+
await fs13.writeFile(path16.join(exercisePath, "setup.sh"), setupSh, "utf-8");
|
|
20768
20755
|
extractedFiles.push("setup.sh");
|
|
20769
20756
|
}
|
|
20770
20757
|
}
|
|
20771
20758
|
const readme = generateReadme(lessonData, exerciseTier);
|
|
20772
|
-
const readmePath =
|
|
20773
|
-
await
|
|
20759
|
+
const readmePath = path16.join(exercisePath, "README.md");
|
|
20760
|
+
await fs13.writeFile(readmePath, readme, "utf-8");
|
|
20774
20761
|
extractedFiles.push("README.md");
|
|
20775
20762
|
return {
|
|
20776
20763
|
exercisePath,
|
|
@@ -20852,9 +20839,9 @@ var init_workspace = __esm({
|
|
|
20852
20839
|
|
|
20853
20840
|
// src/commands/workspace.ts
|
|
20854
20841
|
import { Command as Command17 } from "commander";
|
|
20855
|
-
import
|
|
20842
|
+
import path17 from "node:path";
|
|
20856
20843
|
import os8 from "node:os";
|
|
20857
|
-
import
|
|
20844
|
+
import fs14 from "node:fs/promises";
|
|
20858
20845
|
var logger18, workspaceCommand;
|
|
20859
20846
|
var init_workspace2 = __esm({
|
|
20860
20847
|
"src/commands/workspace.ts"() {
|
|
@@ -20878,14 +20865,14 @@ var init_workspace2 = __esm({
|
|
|
20878
20865
|
let directories;
|
|
20879
20866
|
if (!opts.path && cwdIsWorkspace) {
|
|
20880
20867
|
const resolvedCwd = await resolveCwdWorkspacePath(process.cwd());
|
|
20881
|
-
workspacePath = resolvedCwd ??
|
|
20882
|
-
await
|
|
20868
|
+
workspacePath = resolvedCwd ?? path17.join(process.cwd(), ".tostudy");
|
|
20869
|
+
await fs14.mkdir(workspacePath, { recursive: true });
|
|
20883
20870
|
directories = ["exercises", "generated", "notes", "diagrams"];
|
|
20884
20871
|
for (const dir of directories) {
|
|
20885
|
-
await
|
|
20872
|
+
await fs14.mkdir(path17.join(workspacePath, dir), { recursive: true });
|
|
20886
20873
|
}
|
|
20887
|
-
const configPath =
|
|
20888
|
-
await
|
|
20874
|
+
const configPath = path17.join(workspacePath, ".ana-config.json");
|
|
20875
|
+
await fs14.writeFile(
|
|
20889
20876
|
configPath,
|
|
20890
20877
|
JSON.stringify(
|
|
20891
20878
|
{
|
|
@@ -20903,7 +20890,7 @@ var init_workspace2 = __esm({
|
|
|
20903
20890
|
"utf-8"
|
|
20904
20891
|
);
|
|
20905
20892
|
} else {
|
|
20906
|
-
const basePath = opts.path ??
|
|
20893
|
+
const basePath = opts.path ?? path17.join(os8.homedir(), "study");
|
|
20907
20894
|
const result2 = await setupWorkspace({
|
|
20908
20895
|
courseId: activeCourse.courseId,
|
|
20909
20896
|
courseSlug: courseSlug(activeCourse.courseTitle),
|
|
@@ -20937,7 +20924,7 @@ Pr\xF3ximo passo: tostudy export
|
|
|
20937
20924
|
process.exit(1);
|
|
20938
20925
|
}
|
|
20939
20926
|
});
|
|
20940
|
-
workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
20927
|
+
workspaceCommand.command("status").description("Mostrar status do workspace do curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path17.join(os8.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
20941
20928
|
try {
|
|
20942
20929
|
const activeCourse = await requireActiveCourse();
|
|
20943
20930
|
const onboardingState = await getCourseOnboardingState(activeCourse.courseId);
|
|
@@ -20954,40 +20941,40 @@ Pr\xF3ximo passo: tostudy export
|
|
|
20954
20941
|
const workspacePath = ws.workspacePath;
|
|
20955
20942
|
let configData = null;
|
|
20956
20943
|
try {
|
|
20957
|
-
const raw = await
|
|
20944
|
+
const raw = await fs14.readFile(path17.join(workspacePath, ".ana-config.json"), "utf-8");
|
|
20958
20945
|
configData = JSON.parse(raw);
|
|
20959
20946
|
} catch {
|
|
20960
20947
|
configData = null;
|
|
20961
20948
|
}
|
|
20962
|
-
const exercisesDir =
|
|
20949
|
+
const exercisesDir = path17.join(workspacePath, "exercises");
|
|
20963
20950
|
let exerciseCount = 0;
|
|
20964
20951
|
try {
|
|
20965
|
-
const moduleDirs = await
|
|
20952
|
+
const moduleDirs = await fs14.readdir(exercisesDir);
|
|
20966
20953
|
for (const modDir of moduleDirs) {
|
|
20967
|
-
const modPath =
|
|
20968
|
-
const stat = await
|
|
20954
|
+
const modPath = path17.join(exercisesDir, modDir);
|
|
20955
|
+
const stat = await fs14.stat(modPath);
|
|
20969
20956
|
if (stat.isDirectory()) {
|
|
20970
|
-
const lessonDirs = await
|
|
20957
|
+
const lessonDirs = await fs14.readdir(modPath);
|
|
20971
20958
|
for (const lessonDir of lessonDirs) {
|
|
20972
|
-
const lessonPath =
|
|
20973
|
-
const lstat = await
|
|
20959
|
+
const lessonPath = path17.join(modPath, lessonDir);
|
|
20960
|
+
const lstat = await fs14.stat(lessonPath);
|
|
20974
20961
|
if (lstat.isDirectory()) exerciseCount++;
|
|
20975
20962
|
}
|
|
20976
20963
|
}
|
|
20977
20964
|
}
|
|
20978
20965
|
} catch {
|
|
20979
20966
|
}
|
|
20980
|
-
const generatedDir =
|
|
20967
|
+
const generatedDir = path17.join(workspacePath, "generated");
|
|
20981
20968
|
let artifactCount = 0;
|
|
20982
20969
|
try {
|
|
20983
|
-
const files = await
|
|
20970
|
+
const files = await fs14.readdir(generatedDir);
|
|
20984
20971
|
artifactCount = files.length;
|
|
20985
20972
|
} catch {
|
|
20986
20973
|
}
|
|
20987
|
-
const diagramsDir =
|
|
20974
|
+
const diagramsDir = path17.join(workspacePath, "diagrams");
|
|
20988
20975
|
let diagramCount = 0;
|
|
20989
20976
|
try {
|
|
20990
|
-
const files = await
|
|
20977
|
+
const files = await fs14.readdir(diagramsDir);
|
|
20991
20978
|
diagramCount = files.length;
|
|
20992
20979
|
} catch {
|
|
20993
20980
|
}
|
|
@@ -21036,9 +21023,9 @@ Pr\xF3ximo passo: tostudy export
|
|
|
21036
21023
|
|
|
21037
21024
|
// src/commands/export.ts
|
|
21038
21025
|
import { Command as Command18 } from "commander";
|
|
21039
|
-
import
|
|
21026
|
+
import path18 from "node:path";
|
|
21040
21027
|
import os9 from "node:os";
|
|
21041
|
-
import
|
|
21028
|
+
import fs15 from "node:fs/promises";
|
|
21042
21029
|
var logger19, exportCommand;
|
|
21043
21030
|
var init_export = __esm({
|
|
21044
21031
|
"src/commands/export.ts"() {
|
|
@@ -21051,7 +21038,7 @@ var init_export = __esm({
|
|
|
21051
21038
|
init_resolve();
|
|
21052
21039
|
init_errors();
|
|
21053
21040
|
logger19 = createLogger("cli:export");
|
|
21054
|
-
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",
|
|
21041
|
+
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(os9.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
21055
21042
|
try {
|
|
21056
21043
|
const session = await requireSession();
|
|
21057
21044
|
const activeCourse = await requireActiveCourse();
|
|
@@ -21069,21 +21056,21 @@ var init_export = __esm({
|
|
|
21069
21056
|
opts.path
|
|
21070
21057
|
);
|
|
21071
21058
|
if (ws.found && ws.source === "cwd" && ws.workspacePath) {
|
|
21072
|
-
const configPath =
|
|
21059
|
+
const configPath = path18.join(ws.workspacePath, ".ana-config.json");
|
|
21073
21060
|
let hasConfig = false;
|
|
21074
21061
|
try {
|
|
21075
|
-
await
|
|
21062
|
+
await fs15.access(configPath);
|
|
21076
21063
|
hasConfig = true;
|
|
21077
21064
|
} catch {
|
|
21078
21065
|
}
|
|
21079
21066
|
if (!hasConfig) {
|
|
21080
21067
|
const slug = courseSlug(activeCourse.courseTitle);
|
|
21081
21068
|
logger19.info("Auto-initializing workspace", { workspacePath: ws.workspacePath });
|
|
21082
|
-
await
|
|
21069
|
+
await fs15.mkdir(ws.workspacePath, { recursive: true });
|
|
21083
21070
|
for (const dir of ["exercises", "generated", "notes", "diagrams"]) {
|
|
21084
|
-
await
|
|
21071
|
+
await fs15.mkdir(path18.join(ws.workspacePath, dir), { recursive: true });
|
|
21085
21072
|
}
|
|
21086
|
-
await
|
|
21073
|
+
await fs15.writeFile(
|
|
21087
21074
|
configPath,
|
|
21088
21075
|
JSON.stringify(
|
|
21089
21076
|
{
|
|
@@ -21101,7 +21088,7 @@ var init_export = __esm({
|
|
|
21101
21088
|
"utf-8"
|
|
21102
21089
|
);
|
|
21103
21090
|
await setCourseWorkspacePath(activeCourse.courseId, ws.workspacePath);
|
|
21104
|
-
const isNamespaced = ws.workspacePath ===
|
|
21091
|
+
const isNamespaced = ws.workspacePath === path18.join(process.cwd(), ".tostudy");
|
|
21105
21092
|
process.stderr.write(
|
|
21106
21093
|
isNamespaced ? `\u2728 Workspace inicializado em .tostudy/ (isolado do projeto).
|
|
21107
21094
|
` : `\u2728 Workspace inicializado nesta pasta.
|
|
@@ -21155,7 +21142,7 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
|
|
|
21155
21142
|
// src/commands/open.ts
|
|
21156
21143
|
import { Command as Command19 } from "commander";
|
|
21157
21144
|
import { execFile as execFile3 } from "node:child_process";
|
|
21158
|
-
import
|
|
21145
|
+
import path19 from "node:path";
|
|
21159
21146
|
import os10 from "node:os";
|
|
21160
21147
|
var logger20, openCommand;
|
|
21161
21148
|
var init_open = __esm({
|
|
@@ -21167,7 +21154,7 @@ var init_open = __esm({
|
|
|
21167
21154
|
init_resolve();
|
|
21168
21155
|
init_errors();
|
|
21169
21156
|
logger20 = createLogger("cli:open");
|
|
21170
|
-
openCommand = new Command19("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
21157
|
+
openCommand = new Command19("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path19.join(os10.homedir(), "study")).action(async (opts) => {
|
|
21171
21158
|
try {
|
|
21172
21159
|
const activeCourse = await requireActiveCourse();
|
|
21173
21160
|
const onboardingState = await getCourseOnboardingState(activeCourse.courseId);
|
|
@@ -21221,24 +21208,24 @@ var init_types = __esm({
|
|
|
21221
21208
|
});
|
|
21222
21209
|
|
|
21223
21210
|
// ../../packages/tostudy-core/src/vault/write-vault.ts
|
|
21224
|
-
import
|
|
21225
|
-
import
|
|
21211
|
+
import fs16 from "node:fs/promises";
|
|
21212
|
+
import path20 from "node:path";
|
|
21226
21213
|
async function writeVaultFiles(files, outputPath, courseId, courseSlug2) {
|
|
21227
21214
|
for (const file2 of files) {
|
|
21228
|
-
const fullPath =
|
|
21229
|
-
await
|
|
21230
|
-
await
|
|
21215
|
+
const fullPath = path20.join(outputPath, file2.relativePath);
|
|
21216
|
+
await fs16.mkdir(path20.dirname(fullPath), { recursive: true });
|
|
21217
|
+
await fs16.writeFile(fullPath, file2.content, "utf-8");
|
|
21231
21218
|
}
|
|
21232
|
-
const vaultPath =
|
|
21219
|
+
const vaultPath = path20.join(outputPath, courseSlug2);
|
|
21233
21220
|
const marker = {
|
|
21234
21221
|
courseId,
|
|
21235
21222
|
courseSlug: courseSlug2,
|
|
21236
21223
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21237
21224
|
version: VAULT_MARKER_VERSION
|
|
21238
21225
|
};
|
|
21239
|
-
await
|
|
21240
|
-
await
|
|
21241
|
-
|
|
21226
|
+
await fs16.mkdir(vaultPath, { recursive: true });
|
|
21227
|
+
await fs16.writeFile(
|
|
21228
|
+
path20.join(vaultPath, VAULT_MARKER_FILENAME),
|
|
21242
21229
|
JSON.stringify(marker, null, 2),
|
|
21243
21230
|
"utf-8"
|
|
21244
21231
|
);
|
|
@@ -21263,9 +21250,9 @@ var init_vault = __esm({
|
|
|
21263
21250
|
|
|
21264
21251
|
// src/commands/vault.ts
|
|
21265
21252
|
import { Command as Command20 } from "commander";
|
|
21266
|
-
import
|
|
21253
|
+
import path21 from "node:path";
|
|
21267
21254
|
import os11 from "node:os";
|
|
21268
|
-
import
|
|
21255
|
+
import fs17 from "node:fs/promises";
|
|
21269
21256
|
var logger21, vaultCommand;
|
|
21270
21257
|
var init_vault2 = __esm({
|
|
21271
21258
|
"src/commands/vault.ts"() {
|
|
@@ -21281,7 +21268,7 @@ var init_vault2 = __esm({
|
|
|
21281
21268
|
init_errors();
|
|
21282
21269
|
logger21 = createLogger("cli:vault");
|
|
21283
21270
|
vaultCommand = new Command20("vault").description("Gerenciar vault Obsidian do curso");
|
|
21284
|
-
vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
21271
|
+
vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path21.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
21285
21272
|
try {
|
|
21286
21273
|
const session = await requireSession();
|
|
21287
21274
|
const activeCourse = await requireActiveCourse();
|
|
@@ -21362,7 +21349,7 @@ Para visualizar:
|
|
|
21362
21349
|
process.exit(1);
|
|
21363
21350
|
}
|
|
21364
21351
|
});
|
|
21365
|
-
vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace",
|
|
21352
|
+
vaultCommand.command("sync").description("Sincronizar progresso do curso com o vault local").option("--path <dir>", "Diret\xF3rio base do workspace", path21.join(os11.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
21366
21353
|
try {
|
|
21367
21354
|
const session = await requireSession();
|
|
21368
21355
|
const activeCourse = await requireActiveCourse();
|
|
@@ -21388,8 +21375,8 @@ Para visualizar:
|
|
|
21388
21375
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
21389
21376
|
const deps = { data, logger: logger21 };
|
|
21390
21377
|
const progress = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
21391
|
-
const markerPath =
|
|
21392
|
-
const markerRaw = await
|
|
21378
|
+
const markerPath = path21.join(vaultPath, ".ana-vault.json");
|
|
21379
|
+
const markerRaw = await fs17.readFile(markerPath, "utf-8");
|
|
21393
21380
|
const marker = JSON.parse(markerRaw);
|
|
21394
21381
|
marker.lastSyncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21395
21382
|
marker.progress = {
|
|
@@ -21397,10 +21384,10 @@ Para visualizar:
|
|
|
21397
21384
|
currentModule: progress.currentModule.title,
|
|
21398
21385
|
currentLesson: progress.currentLesson.title
|
|
21399
21386
|
};
|
|
21400
|
-
await
|
|
21401
|
-
const courseIndexPath =
|
|
21387
|
+
await fs17.writeFile(markerPath, JSON.stringify(marker, null, 2), "utf-8");
|
|
21388
|
+
const courseIndexPath = path21.join(vaultPath, slug, "index.md");
|
|
21402
21389
|
try {
|
|
21403
|
-
let indexContent = await
|
|
21390
|
+
let indexContent = await fs17.readFile(courseIndexPath, "utf-8");
|
|
21404
21391
|
indexContent = indexContent.replace(/\n---\n\n> 📊 Progresso:.*\n/g, "");
|
|
21405
21392
|
const titleEnd = indexContent.indexOf("\n");
|
|
21406
21393
|
if (titleEnd !== -1) {
|
|
@@ -21411,7 +21398,7 @@ Para visualizar:
|
|
|
21411
21398
|
`;
|
|
21412
21399
|
indexContent = indexContent.slice(0, titleEnd) + banner + indexContent.slice(titleEnd);
|
|
21413
21400
|
}
|
|
21414
|
-
await
|
|
21401
|
+
await fs17.writeFile(courseIndexPath, indexContent, "utf-8");
|
|
21415
21402
|
} catch {
|
|
21416
21403
|
}
|
|
21417
21404
|
const syncedAt = marker.lastSyncedAt;
|
|
@@ -21731,16 +21718,16 @@ var init_brief_open = __esm({
|
|
|
21731
21718
|
});
|
|
21732
21719
|
|
|
21733
21720
|
// src/sessions/storage.ts
|
|
21734
|
-
import
|
|
21735
|
-
import
|
|
21721
|
+
import fs18 from "node:fs";
|
|
21722
|
+
import path22 from "node:path";
|
|
21736
21723
|
function sessionsDir(workspacePath) {
|
|
21737
|
-
return
|
|
21724
|
+
return path22.join(workspacePath, ".tostudy", "sessions");
|
|
21738
21725
|
}
|
|
21739
21726
|
async function saveModuleSummary(workspacePath, input2) {
|
|
21740
21727
|
const dir = sessionsDir(workspacePath);
|
|
21741
|
-
|
|
21728
|
+
fs18.mkdirSync(dir, { recursive: true });
|
|
21742
21729
|
const filename = `module-${input2.moduleId}-summary.md`;
|
|
21743
|
-
const filePath =
|
|
21730
|
+
const filePath = path22.join(dir, filename);
|
|
21744
21731
|
const header = [
|
|
21745
21732
|
"---",
|
|
21746
21733
|
`moduleId: ${input2.moduleId}`,
|
|
@@ -21749,17 +21736,17 @@ async function saveModuleSummary(workspacePath, input2) {
|
|
|
21749
21736
|
"---",
|
|
21750
21737
|
""
|
|
21751
21738
|
].join("\n");
|
|
21752
|
-
|
|
21739
|
+
fs18.writeFileSync(filePath, header + input2.summary, { mode: 384 });
|
|
21753
21740
|
logger25.debug("Module summary saved", { moduleId: input2.moduleId, path: filePath });
|
|
21754
21741
|
return filePath;
|
|
21755
21742
|
}
|
|
21756
21743
|
async function loadSessionContext(workspacePath) {
|
|
21757
21744
|
const dir = sessionsDir(workspacePath);
|
|
21758
|
-
if (!
|
|
21759
|
-
const files =
|
|
21745
|
+
if (!fs18.existsSync(dir)) return { moduleSummaries: [] };
|
|
21746
|
+
const files = fs18.readdirSync(dir).filter((f) => f.startsWith("module-") && f.endsWith("-summary.md")).sort();
|
|
21760
21747
|
const summaries = [];
|
|
21761
21748
|
for (const file2 of files) {
|
|
21762
|
-
const content =
|
|
21749
|
+
const content = fs18.readFileSync(path22.join(dir, file2), "utf-8");
|
|
21763
21750
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
21764
21751
|
if (!frontmatterMatch) continue;
|
|
21765
21752
|
const meta3 = frontmatterMatch[1];
|
|
@@ -21781,7 +21768,7 @@ var init_storage = __esm({
|
|
|
21781
21768
|
});
|
|
21782
21769
|
|
|
21783
21770
|
// src/commands/compact.ts
|
|
21784
|
-
import
|
|
21771
|
+
import fs19 from "node:fs";
|
|
21785
21772
|
import { Command as Command26 } from "commander";
|
|
21786
21773
|
var logger26, compactCommand;
|
|
21787
21774
|
var init_compact = __esm({
|
|
@@ -21801,7 +21788,7 @@ var init_compact = __esm({
|
|
|
21801
21788
|
if (opts.json) jsonError("no_workspace");
|
|
21802
21789
|
error("Nenhum workspace encontrado.");
|
|
21803
21790
|
}
|
|
21804
|
-
const summary =
|
|
21791
|
+
const summary = fs19.readFileSync("/dev/stdin", "utf-8").trim();
|
|
21805
21792
|
if (!summary) {
|
|
21806
21793
|
if (opts.json) jsonError("empty_summary", { message: "Summary vazio" });
|
|
21807
21794
|
error("Summary vazio. Envie o conte\xFAdo via stdin.");
|
|
@@ -23055,11 +23042,11 @@ __export(auto_updater_exports, {
|
|
|
23055
23042
|
detectManager: () => detectManager,
|
|
23056
23043
|
maybeAutoUpdate: () => maybeAutoUpdate
|
|
23057
23044
|
});
|
|
23058
|
-
import
|
|
23059
|
-
import
|
|
23045
|
+
import fs20 from "node:fs";
|
|
23046
|
+
import path23 from "node:path";
|
|
23060
23047
|
import { spawn as spawn2 } from "node:child_process";
|
|
23061
23048
|
function detectManager(entryRealPath) {
|
|
23062
|
-
const p = entryRealPath.split(
|
|
23049
|
+
const p = entryRealPath.split(path23.sep).join("/");
|
|
23063
23050
|
if (p.includes("/pnpm/")) return { cmd: "pnpm", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
|
|
23064
23051
|
if (p.includes("/.bun/")) return { cmd: "bun", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
|
|
23065
23052
|
if (p.includes(`/node_modules/${PACKAGE_NAME2}/`))
|
|
@@ -23067,10 +23054,10 @@ function detectManager(entryRealPath) {
|
|
|
23067
23054
|
return null;
|
|
23068
23055
|
}
|
|
23069
23056
|
function installDir(entryRealPath) {
|
|
23070
|
-
const normalized = entryRealPath.split(
|
|
23057
|
+
const normalized = entryRealPath.split(path23.sep).join("/");
|
|
23071
23058
|
const marker = `/node_modules/${PACKAGE_NAME2}/`;
|
|
23072
23059
|
const idx = normalized.indexOf(marker);
|
|
23073
|
-
if (idx === -1) return
|
|
23060
|
+
if (idx === -1) return path23.dirname(entryRealPath);
|
|
23074
23061
|
return entryRealPath.slice(0, idx + marker.length - 1);
|
|
23075
23062
|
}
|
|
23076
23063
|
function maybeAutoUpdate(currentVersion, opts = {}) {
|
|
@@ -23086,10 +23073,10 @@ function maybeAutoUpdate(currentVersion, opts = {}) {
|
|
|
23086
23073
|
if (cache.attemptedVersion === cache.latest) return;
|
|
23087
23074
|
const entryPath = opts.entryPath ?? argv[1];
|
|
23088
23075
|
if (!entryPath) return;
|
|
23089
|
-
const real =
|
|
23076
|
+
const real = fs20.realpathSync(entryPath);
|
|
23090
23077
|
const mgr = detectManager(real);
|
|
23091
23078
|
if (!mgr) return;
|
|
23092
|
-
|
|
23079
|
+
fs20.accessSync(installDir(real), fs20.constants.W_OK);
|
|
23093
23080
|
writeCache({ ...cache, attemptedVersion: cache.latest }, configDir);
|
|
23094
23081
|
process.stderr.write(
|
|
23095
23082
|
`
|
|
@@ -23132,6 +23119,18 @@ Update at https://nodejs.org and run the command again.
|
|
|
23132
23119
|
);
|
|
23133
23120
|
process.exit(1);
|
|
23134
23121
|
}
|
|
23122
|
+
if (!process.env["TOSTUDY_LOCALE"]) {
|
|
23123
|
+
try {
|
|
23124
|
+
const { readFileSync: readFileSync4 } = await import("node:fs");
|
|
23125
|
+
const { join: join3 } = await import("node:path");
|
|
23126
|
+
const { homedir: homedir2 } = await import("node:os");
|
|
23127
|
+
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
23128
|
+
const dir = process.platform === "linux" && xdg ? join3(xdg, "tostudy") : join3(homedir2(), ".tostudy");
|
|
23129
|
+
const { locale } = JSON.parse(readFileSync4(join3(dir, "config.json"), "utf-8"));
|
|
23130
|
+
if (locale === "pt-BR" || locale === "en-US") process.env["TOSTUDY_LOCALE"] = locale;
|
|
23131
|
+
} catch {
|
|
23132
|
+
}
|
|
23133
|
+
}
|
|
23135
23134
|
var { createProgram: createProgram2, CLI_VERSION: CLI_VERSION2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
23136
23135
|
var { checkForUpdates: checkForUpdates2 } = await Promise.resolve().then(() => (init_update_checker(), update_checker_exports));
|
|
23137
23136
|
var { maybeAutoUpdate: maybeAutoUpdate2 } = await Promise.resolve().then(() => (init_auto_updater(), auto_updater_exports));
|