@tostudy-ai/cli 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +88 -28
- package/dist/cli.js.map +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1917,6 +1917,13 @@ var init_ide_detector = __esm({
|
|
|
1917
1917
|
});
|
|
1918
1918
|
|
|
1919
1919
|
// src/output/instruction-template-v3.ts
|
|
1920
|
+
var instruction_template_v3_exports = {};
|
|
1921
|
+
__export(instruction_template_v3_exports, {
|
|
1922
|
+
COURSE_TEMPLATE_VERSION: () => COURSE_TEMPLATE_VERSION,
|
|
1923
|
+
UNIVERSAL_TEMPLATE_VERSION: () => UNIVERSAL_TEMPLATE_VERSION,
|
|
1924
|
+
renderCourseInstruction: () => renderCourseInstruction,
|
|
1925
|
+
renderUniversalInstruction: () => renderUniversalInstruction
|
|
1926
|
+
});
|
|
1920
1927
|
function renderCourseInstruction(input2) {
|
|
1921
1928
|
const sections = [];
|
|
1922
1929
|
sections.push(renderTitle(input2));
|
|
@@ -1990,7 +1997,7 @@ Quando \`tostudy next --json\` retornar \`MODULE_COMPLETE\`:
|
|
|
1990
1997
|
Isso garante continuidade entre sess\xF5es e evita estouro de contexto em sess\xF5es longas.`);
|
|
1991
1998
|
sections.push(renderHandlingSituations());
|
|
1992
1999
|
sections.push(renderTechnicalReference());
|
|
1993
|
-
sections.push(`<!-- tostudy-template-version:
|
|
2000
|
+
sections.push(`<!-- tostudy-template-version: ${UNIVERSAL_TEMPLATE_VERSION} -->`);
|
|
1994
2001
|
return sections.join("\n\n") + "\n";
|
|
1995
2002
|
}
|
|
1996
2003
|
function renderTitle(input2) {
|
|
@@ -2235,12 +2242,14 @@ function renderTechnicalReference() {
|
|
|
2235
2242
|
}
|
|
2236
2243
|
function renderFooter(course) {
|
|
2237
2244
|
return `<!-- tostudy-course-id: ${course.courseId} -->
|
|
2238
|
-
<!-- tostudy-template-version:
|
|
2245
|
+
<!-- tostudy-template-version: ${COURSE_TEMPLATE_VERSION} -->`;
|
|
2239
2246
|
}
|
|
2240
|
-
var TONE_LABELS, LEVEL_LABELS;
|
|
2247
|
+
var COURSE_TEMPLATE_VERSION, UNIVERSAL_TEMPLATE_VERSION, TONE_LABELS, LEVEL_LABELS;
|
|
2241
2248
|
var init_instruction_template_v3 = __esm({
|
|
2242
2249
|
"src/output/instruction-template-v3.ts"() {
|
|
2243
2250
|
"use strict";
|
|
2251
|
+
COURSE_TEMPLATE_VERSION = 4;
|
|
2252
|
+
UNIVERSAL_TEMPLATE_VERSION = 5;
|
|
2244
2253
|
TONE_LABELS = {
|
|
2245
2254
|
formal: "formal",
|
|
2246
2255
|
casual: "casual",
|
|
@@ -2972,6 +2981,24 @@ async function writeWorkspaceMarker(workspacePath, input2, options = {}) {
|
|
|
2972
2981
|
}
|
|
2973
2982
|
const existing = await readWorkspaceMarker(workspacePath);
|
|
2974
2983
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2984
|
+
let carried = {};
|
|
2985
|
+
if (existing && existing.courseId === input2.courseId) {
|
|
2986
|
+
try {
|
|
2987
|
+
const raw = JSON.parse(readFileSync2(filePath, "utf-8"));
|
|
2988
|
+
for (const key of [
|
|
2989
|
+
"currentLessonId",
|
|
2990
|
+
"currentModuleId",
|
|
2991
|
+
"courseTags",
|
|
2992
|
+
"courseLevel",
|
|
2993
|
+
"lastInitCourseId",
|
|
2994
|
+
"templateVersion"
|
|
2995
|
+
]) {
|
|
2996
|
+
if (raw[key] !== void 0) carried[key] = raw[key];
|
|
2997
|
+
}
|
|
2998
|
+
} catch {
|
|
2999
|
+
carried = {};
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
2975
3002
|
const marker = {
|
|
2976
3003
|
version: CURRENT_VERSION,
|
|
2977
3004
|
courseId: input2.courseId,
|
|
@@ -2981,7 +3008,7 @@ async function writeWorkspaceMarker(workspacePath, input2, options = {}) {
|
|
|
2981
3008
|
createdAt: existing?.createdAt ?? now,
|
|
2982
3009
|
updatedAt: now
|
|
2983
3010
|
};
|
|
2984
|
-
writeFileSync3(filePath, JSON.stringify(marker, null, 2), { mode: 384 });
|
|
3011
|
+
writeFileSync3(filePath, JSON.stringify({ ...carried, ...marker }, null, 2), { mode: 384 });
|
|
2985
3012
|
return filePath;
|
|
2986
3013
|
}
|
|
2987
3014
|
var CURRENT_VERSION, SUPPORTED_VERSIONS;
|
|
@@ -3026,6 +3053,7 @@ async function readWorkspaceState(workspacePath) {
|
|
|
3026
3053
|
state.courseLevel = raw.courseLevel;
|
|
3027
3054
|
}
|
|
3028
3055
|
if (typeof raw.lastInitCourseId === "string") state.lastInitCourseId = raw.lastInitCourseId;
|
|
3056
|
+
if (typeof raw.templateVersion === "number") state.templateVersion = raw.templateVersion;
|
|
3029
3057
|
return state;
|
|
3030
3058
|
} catch {
|
|
3031
3059
|
return null;
|
|
@@ -3079,16 +3107,31 @@ async function setLastInitCourseId(courseId, _configDir) {
|
|
|
3079
3107
|
}
|
|
3080
3108
|
async function checkCourseDrift() {
|
|
3081
3109
|
const { findWorkspaceState: findWorkspaceState2 } = await Promise.resolve().then(() => (init_workspace_state(), workspace_state_exports));
|
|
3110
|
+
const { COURSE_TEMPLATE_VERSION: COURSE_TEMPLATE_VERSION2 } = await Promise.resolve().then(() => (init_instruction_template_v3(), instruction_template_v3_exports));
|
|
3082
3111
|
const result = await findWorkspaceState2();
|
|
3083
3112
|
if (!result) return null;
|
|
3084
3113
|
const state = result.state;
|
|
3085
|
-
|
|
3086
|
-
if (state.lastInitCourseId
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3114
|
+
const warnings = [];
|
|
3115
|
+
if (state.lastInitCourseId && state.lastInitCourseId !== state.courseId) {
|
|
3116
|
+
warnings.push(
|
|
3117
|
+
[
|
|
3118
|
+
`\u26A0\uFE0F Curso ativo mudou para "${state.courseTitle}".`,
|
|
3119
|
+
` Rode \`tostudy init\` para atualizar o contexto do assistente.`,
|
|
3120
|
+
""
|
|
3121
|
+
].join("\n")
|
|
3122
|
+
);
|
|
3123
|
+
}
|
|
3124
|
+
if ((state.templateVersion ?? 0) < COURSE_TEMPLATE_VERSION2) {
|
|
3125
|
+
const from = state.templateVersion ? `v${state.templateVersion}` : "vers\xE3o antiga";
|
|
3126
|
+
warnings.push(
|
|
3127
|
+
[
|
|
3128
|
+
`\u26A0\uFE0F As instru\xE7\xF5es do tutor neste workspace est\xE3o desatualizadas (${from} < v${COURSE_TEMPLATE_VERSION2}).`,
|
|
3129
|
+
` Rode \`tostudy sync\` para atualizar as regras do tutor.`,
|
|
3130
|
+
""
|
|
3131
|
+
].join("\n")
|
|
3132
|
+
);
|
|
3133
|
+
}
|
|
3134
|
+
return warnings.length > 0 ? warnings.join("\n") : null;
|
|
3092
3135
|
}
|
|
3093
3136
|
var init_course_drift = __esm({
|
|
3094
3137
|
"src/onboarding/course-drift.ts"() {
|
|
@@ -3479,7 +3522,7 @@ var CLI_VERSION;
|
|
|
3479
3522
|
var init_version = __esm({
|
|
3480
3523
|
"src/version.ts"() {
|
|
3481
3524
|
"use strict";
|
|
3482
|
-
CLI_VERSION = true ? "0.17.
|
|
3525
|
+
CLI_VERSION = true ? "0.17.1" : "0.7.1";
|
|
3483
3526
|
}
|
|
3484
3527
|
});
|
|
3485
3528
|
|
|
@@ -4195,13 +4238,18 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
4195
4238
|
} catch (err) {
|
|
4196
4239
|
logger6.warn("Failed to write workspace marker", { err });
|
|
4197
4240
|
}
|
|
4241
|
+
let workspaceStateRecorded = false;
|
|
4198
4242
|
if (markerPath) {
|
|
4199
4243
|
try {
|
|
4200
4244
|
await updateWorkspaceState(context.cwd, {
|
|
4201
4245
|
courseTags: courseMeta.courseTags,
|
|
4202
4246
|
courseLevel: courseMeta.courseLevel,
|
|
4203
|
-
lastInitCourseId: input2.courseId
|
|
4247
|
+
lastInitCourseId: input2.courseId,
|
|
4248
|
+
// GH #1534: record which template generated the instruction files so
|
|
4249
|
+
// checkCourseDrift() can flag stale workspaces after a template bump.
|
|
4250
|
+
templateVersion: COURSE_TEMPLATE_VERSION
|
|
4204
4251
|
});
|
|
4252
|
+
workspaceStateRecorded = true;
|
|
4205
4253
|
} catch (err) {
|
|
4206
4254
|
logger6.warn("Failed to update workspace state v2 fields", {
|
|
4207
4255
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -4215,7 +4263,8 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
4215
4263
|
usedT1: studentBrief !== null,
|
|
4216
4264
|
usedT2: enrollmentProfile !== null,
|
|
4217
4265
|
bootstrapped,
|
|
4218
|
-
renderedInstruction: content
|
|
4266
|
+
renderedInstruction: content,
|
|
4267
|
+
workspaceStateRecorded
|
|
4219
4268
|
};
|
|
4220
4269
|
}
|
|
4221
4270
|
var logger6, defaultDeps2;
|
|
@@ -21609,6 +21658,7 @@ var init_sync = __esm({
|
|
|
21609
21658
|
init_guards();
|
|
21610
21659
|
init_formatter();
|
|
21611
21660
|
init_instruction_pipeline();
|
|
21661
|
+
init_workspace_state();
|
|
21612
21662
|
init_root_agents_consent();
|
|
21613
21663
|
init_pipeline_deps();
|
|
21614
21664
|
logger22 = createLogger("cli:sync");
|
|
@@ -21622,8 +21672,10 @@ var init_sync = __esm({
|
|
|
21622
21672
|
try {
|
|
21623
21673
|
await requireSession();
|
|
21624
21674
|
const activeCourse = await requireActiveCourse();
|
|
21675
|
+
const found = await findWorkspaceState();
|
|
21676
|
+
const workspaceCwd = found?.workspacePath ?? process.cwd();
|
|
21625
21677
|
const rootAgents = await resolveRootAgentsConsent({
|
|
21626
|
-
cwd:
|
|
21678
|
+
cwd: workspaceCwd,
|
|
21627
21679
|
flag: opts.rootAgents,
|
|
21628
21680
|
interactive: isInteractiveTerminal(opts.json)
|
|
21629
21681
|
});
|
|
@@ -21631,7 +21683,7 @@ var init_sync = __esm({
|
|
|
21631
21683
|
{ courseId: activeCourse.courseId, enrollmentId: activeCourse.enrollmentId },
|
|
21632
21684
|
{ forceRefresh: true, collectT1Interactive: false, collectT2Interactive: false },
|
|
21633
21685
|
{
|
|
21634
|
-
cwd:
|
|
21686
|
+
cwd: workspaceCwd,
|
|
21635
21687
|
deps: buildPipelineDeps({
|
|
21636
21688
|
allRuntimes: opts.allRuntimes,
|
|
21637
21689
|
rootAgentsConsent: rootAgents.consent
|
|
@@ -21651,21 +21703,25 @@ var init_sync = __esm({
|
|
|
21651
21703
|
markerPath: pipelineResult.markerPath,
|
|
21652
21704
|
usedT0: pipelineResult.usedT0,
|
|
21653
21705
|
usedT1: pipelineResult.usedT1,
|
|
21654
|
-
usedT2: pipelineResult.usedT2
|
|
21706
|
+
usedT2: pipelineResult.usedT2,
|
|
21707
|
+
workspaceStateRecorded: pipelineResult.workspaceStateRecorded
|
|
21655
21708
|
},
|
|
21656
21709
|
{ json: true }
|
|
21657
21710
|
);
|
|
21658
21711
|
} else {
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21712
|
+
const lines = [
|
|
21713
|
+
`\u2713 Instru\xE7\xF5es sincronizadas para "${activeCourse.courseTitle}"`,
|
|
21714
|
+
` - T0 (persona): ${pipelineResult.usedT0 ? "presente" : "ausente"}`,
|
|
21715
|
+
` - T1 (brief base): ${pipelineResult.usedT1 ? "presente" : "ausente"}`,
|
|
21716
|
+
` - T2 (curso): ${pipelineResult.usedT2 ? "presente" : "ausente"}`,
|
|
21717
|
+
` - Arquivos: ${pipelineResult.wroteFiles.join(", ")}`
|
|
21718
|
+
];
|
|
21719
|
+
if (!pipelineResult.workspaceStateRecorded) {
|
|
21720
|
+
lines.push(
|
|
21721
|
+
`\u26A0 N\xE3o consegui gravar .tostudy/workspace.json \u2014 o aviso de template pode continuar aparecendo. Verifique as permiss\xF5es do diret\xF3rio do workspace.`
|
|
21722
|
+
);
|
|
21723
|
+
}
|
|
21724
|
+
output(lines.join("\n"), { json: false });
|
|
21669
21725
|
}
|
|
21670
21726
|
} catch (err) {
|
|
21671
21727
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -21920,6 +21976,7 @@ var init_context = __esm({
|
|
|
21920
21976
|
init_dist();
|
|
21921
21977
|
init_workspace_state();
|
|
21922
21978
|
init_storage();
|
|
21979
|
+
init_course_state();
|
|
21923
21980
|
init_formatter();
|
|
21924
21981
|
init_errors();
|
|
21925
21982
|
logger27 = createLogger("cli:context");
|
|
@@ -21930,6 +21987,8 @@ var init_context = __esm({
|
|
|
21930
21987
|
if (opts.json) jsonError("no_workspace");
|
|
21931
21988
|
error(getErrors().noActiveCourse.trimEnd());
|
|
21932
21989
|
}
|
|
21990
|
+
const driftWarning = await checkCourseDrift();
|
|
21991
|
+
if (driftWarning && !opts.json) process.stderr.write(driftWarning + "\n");
|
|
21933
21992
|
const sessionCtx = await loadSessionContext(ws.workspacePath);
|
|
21934
21993
|
const result = {
|
|
21935
21994
|
workspace: {
|
|
@@ -21948,7 +22007,8 @@ var init_context = __esm({
|
|
|
21948
22007
|
summary: s.summary,
|
|
21949
22008
|
savedAt: s.savedAt
|
|
21950
22009
|
})),
|
|
21951
|
-
totalModulesCompleted: sessionCtx.moduleSummaries.length
|
|
22010
|
+
totalModulesCompleted: sessionCtx.moduleSummaries.length,
|
|
22011
|
+
driftWarning: driftWarning ?? null
|
|
21952
22012
|
};
|
|
21953
22013
|
logger27.debug("Context loaded", {
|
|
21954
22014
|
courseId: ws.state.courseId,
|