@chalksurf/cli 0.3.0 → 0.3.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/bin/chalksurf.js +314 -1
- package/docs/agents.md +2 -0
- package/docs/manual.md +9 -0
- package/docs/mcp.md +2 -0
- package/package.json +1 -1
package/dist/bin/chalksurf.js
CHANGED
|
@@ -132,6 +132,12 @@ var createApiClient = ({
|
|
|
132
132
|
agentSetExerciseVisibility: async (input) => {
|
|
133
133
|
return await mutation("agentSetExerciseVisibility", input);
|
|
134
134
|
},
|
|
135
|
+
agentStartExerciseTranslationGeneration: async (input) => {
|
|
136
|
+
return await mutation(
|
|
137
|
+
"agentStartExerciseTranslationGeneration",
|
|
138
|
+
input
|
|
139
|
+
);
|
|
140
|
+
},
|
|
135
141
|
agentGetSheet: async (id) => {
|
|
136
142
|
return await query("agentGetSheet", { id });
|
|
137
143
|
},
|
|
@@ -159,6 +165,12 @@ var createApiClient = ({
|
|
|
159
165
|
agentSetSheetVisibility: async (input) => {
|
|
160
166
|
return await mutation("agentSetSheetVisibility", input);
|
|
161
167
|
},
|
|
168
|
+
agentStartSheetTranslationGeneration: async (input) => {
|
|
169
|
+
return await mutation(
|
|
170
|
+
"agentStartSheetTranslationGeneration",
|
|
171
|
+
input
|
|
172
|
+
);
|
|
173
|
+
},
|
|
162
174
|
agentAppendExercisesToSheet: async (input) => {
|
|
163
175
|
return await mutation("agentAppendExercisesToSheet", input);
|
|
164
176
|
},
|
|
@@ -1448,7 +1460,11 @@ var Constants = {
|
|
|
1448
1460
|
"import_sheet_started",
|
|
1449
1461
|
"import_sheet_completed",
|
|
1450
1462
|
"import_sheet_solutions_started",
|
|
1451
|
-
"import_sheet_solutions_completed"
|
|
1463
|
+
"import_sheet_solutions_completed",
|
|
1464
|
+
"generate_exercise_translation_started",
|
|
1465
|
+
"generate_exercise_translation_completed",
|
|
1466
|
+
"generate_sheet_translation_started",
|
|
1467
|
+
"generate_sheet_translation_completed"
|
|
1452
1468
|
],
|
|
1453
1469
|
agent_audit_outcome: ["started", "success", "failed", "denied"],
|
|
1454
1470
|
agent_audit_resource_type: ["exercise", "sheet", "folder", "job", "event"],
|
|
@@ -1680,6 +1696,28 @@ var agentWriteOperationRegistry = {
|
|
|
1680
1696
|
receiptOperation: null,
|
|
1681
1697
|
resourceType: "sheet",
|
|
1682
1698
|
sync: false
|
|
1699
|
+
},
|
|
1700
|
+
generate_exercise_translation_started: {
|
|
1701
|
+
agentToolName: "start_exercise_translation_generation",
|
|
1702
|
+
receiptOperation: null,
|
|
1703
|
+
resourceType: "job",
|
|
1704
|
+
sync: false
|
|
1705
|
+
},
|
|
1706
|
+
generate_exercise_translation_completed: {
|
|
1707
|
+
receiptOperation: null,
|
|
1708
|
+
resourceType: "exercise",
|
|
1709
|
+
sync: false
|
|
1710
|
+
},
|
|
1711
|
+
generate_sheet_translation_started: {
|
|
1712
|
+
agentToolName: "start_sheet_translation_generation",
|
|
1713
|
+
receiptOperation: null,
|
|
1714
|
+
resourceType: "job",
|
|
1715
|
+
sync: false
|
|
1716
|
+
},
|
|
1717
|
+
generate_sheet_translation_completed: {
|
|
1718
|
+
receiptOperation: null,
|
|
1719
|
+
resourceType: "sheet",
|
|
1720
|
+
sync: false
|
|
1683
1721
|
}
|
|
1684
1722
|
};
|
|
1685
1723
|
var agentWriteReceiptOperations = Object.values(agentWriteOperationRegistry).map((operation) => operation.receiptOperation).filter((operation) => Boolean(operation));
|
|
@@ -1979,6 +2017,40 @@ var validateLatexSnippetsAgentInputSchema = strictObject({
|
|
|
1979
2017
|
var validateLatexSnippetsAgentOutputSchema = strictObject({
|
|
1980
2018
|
results: z.array(latexValidationResultSchema)
|
|
1981
2019
|
});
|
|
2020
|
+
var queuedExerciseTranslationJobSchema = strictObject({
|
|
2021
|
+
exerciseId: uuidSchema,
|
|
2022
|
+
jobId: uuidSchema,
|
|
2023
|
+
languages: z.array(z.enum(translationLanguages)).min(1),
|
|
2024
|
+
type: z.literal("exercise_translation_generation")
|
|
2025
|
+
});
|
|
2026
|
+
var queuedSheetTranslationJobSchema = strictObject({
|
|
2027
|
+
exerciseSheetId: uuidSchema,
|
|
2028
|
+
jobId: uuidSchema,
|
|
2029
|
+
language: z.enum(translationLanguages),
|
|
2030
|
+
type: z.literal("exercise_sheet_translation_generation")
|
|
2031
|
+
});
|
|
2032
|
+
var skippedSheetTranslationJobSchema = strictObject({
|
|
2033
|
+
jobId: z.null(),
|
|
2034
|
+
language: z.enum(translationLanguages),
|
|
2035
|
+
reason: z.literal("already_complete"),
|
|
2036
|
+
type: z.literal("exercise_sheet_translation_generation")
|
|
2037
|
+
});
|
|
2038
|
+
var targetTranslationLanguagesSchema = z.array(z.enum(translationLanguages)).min(1).refine((languages) => new Set(languages).size === languages.length, "Target languages must be unique");
|
|
2039
|
+
var startExerciseTranslationGenerationAgentInputSchema = strictObject({
|
|
2040
|
+
id: uuidSchema,
|
|
2041
|
+
targetLanguages: targetTranslationLanguagesSchema
|
|
2042
|
+
});
|
|
2043
|
+
var startExerciseTranslationGenerationAgentOutputSchema = strictObject({
|
|
2044
|
+
jobs: z.array(queuedExerciseTranslationJobSchema)
|
|
2045
|
+
});
|
|
2046
|
+
var startSheetTranslationGenerationAgentInputSchema = strictObject({
|
|
2047
|
+
id: uuidSchema,
|
|
2048
|
+
sourceLanguage: z.enum(translationLanguages).optional(),
|
|
2049
|
+
targetLanguages: targetTranslationLanguagesSchema
|
|
2050
|
+
});
|
|
2051
|
+
var startSheetTranslationGenerationAgentOutputSchema = strictObject({
|
|
2052
|
+
jobs: z.array(z.union([queuedSheetTranslationJobSchema, skippedSheetTranslationJobSchema]))
|
|
2053
|
+
});
|
|
1982
2054
|
var sendUserFeedbackAgentInputSchema = strictObject({
|
|
1983
2055
|
message: feedbackMessageSchema,
|
|
1984
2056
|
userConsent: z.literal(true),
|
|
@@ -2415,6 +2487,10 @@ var setExerciseVisibilityInputSchema = setExerciseVisibilityAgentInputSchema.ext
|
|
|
2415
2487
|
organizationId: organizationIdSchema
|
|
2416
2488
|
});
|
|
2417
2489
|
var setExerciseVisibilityOutputSchema = setExerciseVisibilityAgentOutputSchema;
|
|
2490
|
+
var generateExerciseTranslationJobInputSchema = startExerciseTranslationGenerationAgentInputSchema.extend({
|
|
2491
|
+
organizationId: organizationIdSchema
|
|
2492
|
+
});
|
|
2493
|
+
var generateExerciseTranslationJobOutputSchema = startExerciseTranslationGenerationAgentOutputSchema;
|
|
2418
2494
|
var importExerciseInputSchema = strictObject2({
|
|
2419
2495
|
organizationId: organizationIdSchema,
|
|
2420
2496
|
sources: importSourcesSchema,
|
|
@@ -2485,6 +2561,10 @@ var setSheetVisibilityInputSchema = setSheetVisibilityAgentInputSchema.extend({
|
|
|
2485
2561
|
organizationId: organizationIdSchema
|
|
2486
2562
|
});
|
|
2487
2563
|
var setSheetVisibilityOutputSchema = setSheetVisibilityAgentOutputSchema;
|
|
2564
|
+
var generateSheetTranslationJobInputSchema = startSheetTranslationGenerationAgentInputSchema.extend({
|
|
2565
|
+
organizationId: organizationIdSchema
|
|
2566
|
+
});
|
|
2567
|
+
var generateSheetTranslationJobOutputSchema = startSheetTranslationGenerationAgentOutputSchema;
|
|
2488
2568
|
var appendExercisesToSheetInputSchema = appendExercisesToSheetAgentInputSchema.extend({
|
|
2489
2569
|
organizationId: organizationIdSchema
|
|
2490
2570
|
});
|
|
@@ -2676,6 +2756,16 @@ var chalksurfMcpToolCapabilities = {
|
|
|
2676
2756
|
requiredPermission: "write",
|
|
2677
2757
|
security: { type: "oauth2", scopes: [chalksurfMcpScopes.write] }
|
|
2678
2758
|
},
|
|
2759
|
+
generate_exercise_translation_job: {
|
|
2760
|
+
name: "generate_exercise_translation_job",
|
|
2761
|
+
title: "Generate exercise translation job",
|
|
2762
|
+
description: "Use this to queue translation generation for one writable ChalkSurf exercise.",
|
|
2763
|
+
inputSchema: generateExerciseTranslationJobInputSchema,
|
|
2764
|
+
outputSchema: generateExerciseTranslationJobOutputSchema,
|
|
2765
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
2766
|
+
requiredPermission: "write",
|
|
2767
|
+
security: { type: "oauth2", scopes: [chalksurfMcpScopes.write] }
|
|
2768
|
+
},
|
|
2679
2769
|
import_exercise: {
|
|
2680
2770
|
name: "import_exercise",
|
|
2681
2771
|
title: "Import exercise",
|
|
@@ -2796,6 +2886,16 @@ var chalksurfMcpToolCapabilities = {
|
|
|
2796
2886
|
requiredPermission: "write",
|
|
2797
2887
|
security: { type: "oauth2", scopes: [chalksurfMcpScopes.write] }
|
|
2798
2888
|
},
|
|
2889
|
+
generate_sheet_translation_job: {
|
|
2890
|
+
name: "generate_sheet_translation_job",
|
|
2891
|
+
title: "Generate sheet translation job",
|
|
2892
|
+
description: "Use this to queue translation generation for one writable ChalkSurf exercise sheet.",
|
|
2893
|
+
inputSchema: generateSheetTranslationJobInputSchema,
|
|
2894
|
+
outputSchema: generateSheetTranslationJobOutputSchema,
|
|
2895
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
2896
|
+
requiredPermission: "write",
|
|
2897
|
+
security: { type: "oauth2", scopes: [chalksurfMcpScopes.write] }
|
|
2898
|
+
},
|
|
2799
2899
|
append_exercises_to_sheet: {
|
|
2800
2900
|
name: "append_exercises_to_sheet",
|
|
2801
2901
|
title: "Append exercises to sheet",
|
|
@@ -5053,6 +5153,13 @@ var formatUpdateExerciseOutput = ({ receipt }) => {
|
|
|
5053
5153
|
var formatSetExerciseVisibilityOutput = ({ receipt }) => {
|
|
5054
5154
|
return formatAgentWriteReceiptOutput({ receipt });
|
|
5055
5155
|
};
|
|
5156
|
+
var getExerciseTranslationJobIds = ({ jobs }) => jobs.map((job) => job.jobId);
|
|
5157
|
+
var formatExerciseTranslationOutput = ({ jobs }) => {
|
|
5158
|
+
if (jobs.length === 0) {
|
|
5159
|
+
return "No exercise translation jobs queued.";
|
|
5160
|
+
}
|
|
5161
|
+
return jobs.map((job) => `${job.jobId} exercise ${job.exerciseId} ${job.languages.join(", ")}`).join("\n");
|
|
5162
|
+
};
|
|
5056
5163
|
var resolveVisibilityFlag = ({ privateFlag, publicFlag }) => {
|
|
5057
5164
|
if (publicFlag && privateFlag) {
|
|
5058
5165
|
throw new CliCommandError("--public and --private cannot be used together.", 2);
|
|
@@ -5719,6 +5826,98 @@ var registerExerciseCommands = (exerciseYargs, context) => {
|
|
|
5719
5826
|
}
|
|
5720
5827
|
);
|
|
5721
5828
|
}
|
|
5829
|
+
).command(
|
|
5830
|
+
"translate [exerciseId]",
|
|
5831
|
+
"Queue translation generation for an existing exercise",
|
|
5832
|
+
(translateYargs) => translateYargs.positional("exerciseId", {
|
|
5833
|
+
type: "string",
|
|
5834
|
+
describe: "Exercise ID to translate"
|
|
5835
|
+
}).option("translate-to", {
|
|
5836
|
+
array: true,
|
|
5837
|
+
type: "string",
|
|
5838
|
+
describe: `Generate translated exercise content for these languages (${translationLanguages2.join(", ")})`
|
|
5839
|
+
}).option("timeout-ms", {
|
|
5840
|
+
type: "number",
|
|
5841
|
+
default: 3e5,
|
|
5842
|
+
describe: "Maximum time to wait before timing out"
|
|
5843
|
+
}).option("wait", {
|
|
5844
|
+
type: "boolean",
|
|
5845
|
+
default: false,
|
|
5846
|
+
describe: "Wait for the queued translation job to finish"
|
|
5847
|
+
}).example(
|
|
5848
|
+
"chalksurf exercise translate 00000000-0000-4000-8000-000000000001 --translate-to english --json",
|
|
5849
|
+
"Queue exercise translation generation"
|
|
5850
|
+
),
|
|
5851
|
+
async (argv) => {
|
|
5852
|
+
const id = resolveRequestedUuid({
|
|
5853
|
+
fallbackValue: argv.exerciseId,
|
|
5854
|
+
label: "exerciseId",
|
|
5855
|
+
required: true
|
|
5856
|
+
});
|
|
5857
|
+
const targetLanguages = resolveRequestedTranslateToLanguages(argv.translateTo);
|
|
5858
|
+
if (!targetLanguages || targetLanguages.length === 0) {
|
|
5859
|
+
throw new CliCommandError("--translate-to is required at least once.", 2);
|
|
5860
|
+
}
|
|
5861
|
+
const input = { id, targetLanguages };
|
|
5862
|
+
const { apiClient, organizationId } = await createResolvedApiClient({
|
|
5863
|
+
context,
|
|
5864
|
+
baseUrlFlagValue: argv.baseUrl,
|
|
5865
|
+
organizationFlagValue: argv.organization,
|
|
5866
|
+
profileName: argv.profile
|
|
5867
|
+
});
|
|
5868
|
+
let result;
|
|
5869
|
+
try {
|
|
5870
|
+
result = await apiClient.agentStartExerciseTranslationGeneration(input);
|
|
5871
|
+
} catch (error) {
|
|
5872
|
+
throw mapApiErrorToCliError(error);
|
|
5873
|
+
}
|
|
5874
|
+
if (argv.wait !== true) {
|
|
5875
|
+
context.output.print(
|
|
5876
|
+
{
|
|
5877
|
+
request: {
|
|
5878
|
+
...input,
|
|
5879
|
+
organizationId: organizationId ?? null,
|
|
5880
|
+
wait: false,
|
|
5881
|
+
timeoutMs: null
|
|
5882
|
+
},
|
|
5883
|
+
jobs: result.jobs
|
|
5884
|
+
},
|
|
5885
|
+
(output) => formatExerciseTranslationOutput({ jobs: output.jobs }),
|
|
5886
|
+
{
|
|
5887
|
+
command: "exercise translate"
|
|
5888
|
+
}
|
|
5889
|
+
);
|
|
5890
|
+
return;
|
|
5891
|
+
}
|
|
5892
|
+
const timeoutMs = normalizeWaitTimeoutMs(argv.timeoutMs);
|
|
5893
|
+
const waitResult = await waitForCliJobs({
|
|
5894
|
+
getUserJob: async (jobId) => await apiClient.getUserJob(jobId),
|
|
5895
|
+
jobIds: getExerciseTranslationJobIds(result),
|
|
5896
|
+
now: context.now,
|
|
5897
|
+
sleep: context.sleep,
|
|
5898
|
+
timeoutMs
|
|
5899
|
+
});
|
|
5900
|
+
const waitError = getWaitError(waitResult);
|
|
5901
|
+
context.output.print(
|
|
5902
|
+
{
|
|
5903
|
+
request: {
|
|
5904
|
+
...input,
|
|
5905
|
+
organizationId: organizationId ?? null,
|
|
5906
|
+
wait: true,
|
|
5907
|
+
timeoutMs
|
|
5908
|
+
},
|
|
5909
|
+
jobs: result.jobs,
|
|
5910
|
+
wait: waitResult
|
|
5911
|
+
},
|
|
5912
|
+
(output) => output.wait.jobs.map((job) => formatCliJobSummary(job)).join("\n"),
|
|
5913
|
+
{
|
|
5914
|
+
command: "exercise translate",
|
|
5915
|
+
ok: waitError == null,
|
|
5916
|
+
error: waitError
|
|
5917
|
+
}
|
|
5918
|
+
);
|
|
5919
|
+
throwSilentExitCode(getWaitExitCode(waitResult));
|
|
5920
|
+
}
|
|
5722
5921
|
).command(
|
|
5723
5922
|
"validate-latex",
|
|
5724
5923
|
"Validate LaTeX snippets before updating exercise or sheet content",
|
|
@@ -7194,6 +7393,15 @@ var formatUpdateSheetOutput = ({ receipt }) => {
|
|
|
7194
7393
|
var formatSetSheetVisibilityOutput = ({ receipt }) => {
|
|
7195
7394
|
return formatAgentWriteReceiptOutput({ receipt });
|
|
7196
7395
|
};
|
|
7396
|
+
var getSheetTranslationJobIds = ({ jobs }) => jobs.flatMap((job) => job.jobId ? [job.jobId] : []);
|
|
7397
|
+
var formatSheetTranslationOutput = ({ jobs }) => {
|
|
7398
|
+
if (jobs.length === 0 || jobs.every((job) => job.jobId === null)) {
|
|
7399
|
+
return "No sheet translation jobs queued.";
|
|
7400
|
+
}
|
|
7401
|
+
return jobs.map(
|
|
7402
|
+
(job) => job.jobId ? `${job.jobId} sheet ${job.exerciseSheetId} ${job.language}` : `already complete ${job.language}`
|
|
7403
|
+
).join("\n");
|
|
7404
|
+
};
|
|
7197
7405
|
var formatAppendExercisesToSheetOutput = ({ receipt }) => {
|
|
7198
7406
|
return formatAgentWriteReceiptOutput({ receipt });
|
|
7199
7407
|
};
|
|
@@ -7983,6 +8191,111 @@ var registerSheetCommands = (sheetYargs, context) => {
|
|
|
7983
8191
|
}
|
|
7984
8192
|
);
|
|
7985
8193
|
}
|
|
8194
|
+
).command(
|
|
8195
|
+
"translate [exerciseSheetId]",
|
|
8196
|
+
"Queue translation generation for an existing exercise sheet",
|
|
8197
|
+
(translateYargs) => translateYargs.positional("exerciseSheetId", {
|
|
8198
|
+
type: "string",
|
|
8199
|
+
describe: "Exercise sheet ID to translate"
|
|
8200
|
+
}).option("translate-to", {
|
|
8201
|
+
array: true,
|
|
8202
|
+
type: "string",
|
|
8203
|
+
describe: `Generate translated sheet content for these languages (${translationLanguages2.join(", ")})`
|
|
8204
|
+
}).option("source-language", {
|
|
8205
|
+
type: "string",
|
|
8206
|
+
describe: "Preferred source language for sheet metadata translation"
|
|
8207
|
+
}).option("timeout-ms", {
|
|
8208
|
+
type: "number",
|
|
8209
|
+
default: 3e5,
|
|
8210
|
+
describe: "Maximum time to wait before timing out"
|
|
8211
|
+
}).option("wait", {
|
|
8212
|
+
type: "boolean",
|
|
8213
|
+
default: false,
|
|
8214
|
+
describe: "Wait for queued translation jobs to finish"
|
|
8215
|
+
}).example(
|
|
8216
|
+
"chalksurf sheet translate 00000000-0000-4000-8000-000000000001 --translate-to english --json",
|
|
8217
|
+
"Queue sheet translation generation"
|
|
8218
|
+
),
|
|
8219
|
+
async (argv) => {
|
|
8220
|
+
const id = resolveRequestedUuid2({
|
|
8221
|
+
fallbackValue: argv.exerciseSheetId,
|
|
8222
|
+
label: "exerciseSheetId",
|
|
8223
|
+
required: true
|
|
8224
|
+
});
|
|
8225
|
+
const targetLanguages = resolveRequestedTranslateToLanguages(argv.translateTo);
|
|
8226
|
+
if (!targetLanguages || targetLanguages.length === 0) {
|
|
8227
|
+
throw new CliCommandError("--translate-to is required at least once.", 2);
|
|
8228
|
+
}
|
|
8229
|
+
const sourceLanguage = normalizeChoiceValues({
|
|
8230
|
+
allowedValues: translationLanguages2,
|
|
8231
|
+
label: "--source-language",
|
|
8232
|
+
values: argv.sourceLanguage ? [argv.sourceLanguage] : void 0
|
|
8233
|
+
})?.[0];
|
|
8234
|
+
const input = {
|
|
8235
|
+
id,
|
|
8236
|
+
targetLanguages,
|
|
8237
|
+
...sourceLanguage === void 0 ? {} : { sourceLanguage }
|
|
8238
|
+
};
|
|
8239
|
+
const { apiClient, organizationId } = await createResolvedApiClient({
|
|
8240
|
+
context,
|
|
8241
|
+
baseUrlFlagValue: argv.baseUrl,
|
|
8242
|
+
organizationFlagValue: argv.organization,
|
|
8243
|
+
profileName: argv.profile
|
|
8244
|
+
});
|
|
8245
|
+
let result;
|
|
8246
|
+
try {
|
|
8247
|
+
result = await apiClient.agentStartSheetTranslationGeneration(input);
|
|
8248
|
+
} catch (error) {
|
|
8249
|
+
throw mapApiErrorToCliError(error);
|
|
8250
|
+
}
|
|
8251
|
+
if (argv.wait !== true) {
|
|
8252
|
+
context.output.print(
|
|
8253
|
+
{
|
|
8254
|
+
request: {
|
|
8255
|
+
...input,
|
|
8256
|
+
organizationId: organizationId ?? null,
|
|
8257
|
+
wait: false,
|
|
8258
|
+
timeoutMs: null
|
|
8259
|
+
},
|
|
8260
|
+
jobs: result.jobs
|
|
8261
|
+
},
|
|
8262
|
+
(output) => formatSheetTranslationOutput({ jobs: output.jobs }),
|
|
8263
|
+
{
|
|
8264
|
+
command: "sheet translate"
|
|
8265
|
+
}
|
|
8266
|
+
);
|
|
8267
|
+
return;
|
|
8268
|
+
}
|
|
8269
|
+
const timeoutMs = normalizeWaitTimeoutMs(argv.timeoutMs);
|
|
8270
|
+
const jobIds = getSheetTranslationJobIds(result);
|
|
8271
|
+
const waitResult = jobIds.length === 0 ? { jobs: [], timedOut: false } : await waitForCliJobs({
|
|
8272
|
+
getUserJob: async (jobId) => await apiClient.getUserJob(jobId),
|
|
8273
|
+
jobIds,
|
|
8274
|
+
now: context.now,
|
|
8275
|
+
sleep: context.sleep,
|
|
8276
|
+
timeoutMs
|
|
8277
|
+
});
|
|
8278
|
+
const waitError = getWaitError(waitResult);
|
|
8279
|
+
context.output.print(
|
|
8280
|
+
{
|
|
8281
|
+
request: {
|
|
8282
|
+
...input,
|
|
8283
|
+
organizationId: organizationId ?? null,
|
|
8284
|
+
wait: true,
|
|
8285
|
+
timeoutMs
|
|
8286
|
+
},
|
|
8287
|
+
jobs: result.jobs,
|
|
8288
|
+
wait: waitResult
|
|
8289
|
+
},
|
|
8290
|
+
(output) => output.wait.jobs.length > 0 ? output.wait.jobs.map((job) => formatCliJobSummary(job)).join("\n") : formatSheetTranslationOutput({ jobs: output.jobs }),
|
|
8291
|
+
{
|
|
8292
|
+
command: "sheet translate",
|
|
8293
|
+
ok: waitError == null,
|
|
8294
|
+
error: waitError
|
|
8295
|
+
}
|
|
8296
|
+
);
|
|
8297
|
+
throwSilentExitCode(getWaitExitCode(waitResult));
|
|
8298
|
+
}
|
|
7986
8299
|
).command(
|
|
7987
8300
|
"update [exerciseSheetId]",
|
|
7988
8301
|
"Apply a field-level patch to an exercise sheet",
|
package/docs/agents.md
CHANGED
|
@@ -172,6 +172,7 @@ MCP clients should use tool discovery from the client. The ChalkSurf MCP endpoin
|
|
|
172
172
|
| `exercise copy` | `copy_exercise` |
|
|
173
173
|
| `exercise update` | `update_exercise` |
|
|
174
174
|
| `exercise set-visibility` | `set_exercise_visibility` |
|
|
175
|
+
| `exercise translate` | `generate_exercise_translation_job` |
|
|
175
176
|
| `exercise delete` | `delete_exercise` |
|
|
176
177
|
| `exercise validate-latex` | `validate_latex_snippets` |
|
|
177
178
|
| `exercise import` | `import_exercise` |
|
|
@@ -186,6 +187,7 @@ MCP clients should use tool discovery from the client. The ChalkSurf MCP endpoin
|
|
|
186
187
|
| `sheet append` | `append_exercises_to_sheet` |
|
|
187
188
|
| `sheet update` | `update_sheet` |
|
|
188
189
|
| `sheet set-visibility` | `set_sheet_visibility` |
|
|
190
|
+
| `sheet translate` | `generate_sheet_translation_job` |
|
|
189
191
|
| `sheet delete` | `delete_sheet` |
|
|
190
192
|
| `sheet import` | `import_sheet` |
|
|
191
193
|
| `sheet import-solutions` | `import_sheet_solutions` |
|
package/docs/manual.md
CHANGED
|
@@ -162,6 +162,15 @@ chalksurf job wait job_123 job_124
|
|
|
162
162
|
|
|
163
163
|
`--wait` on an import command means the parsed content has been saved before the command exits. Requested translations run as separate jobs; use `--json` to capture their job IDs or `chalksurf job list` to inspect them later.
|
|
164
164
|
|
|
165
|
+
Queue translations for existing resources:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
chalksurf exercise translate 00000000-0000-4000-8000-000000000001 --translate-to english
|
|
169
|
+
chalksurf sheet translate 00000000-0000-4000-8000-000000000002 --translate-to english --source-language hungarian
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Add `--wait` to either translate command to wait for the queued translation job or jobs to finish.
|
|
173
|
+
|
|
165
174
|
## Searching From The CLI
|
|
166
175
|
|
|
167
176
|
Search commands default to `--ownership own`, which means resources in the selected organization.
|
package/docs/mcp.md
CHANGED
|
@@ -43,6 +43,7 @@ Treat write receipts as an agent audit log. They are suitable for user-visible s
|
|
|
43
43
|
| `delete_exercise` | write | Soft-delete one unused writable exercise after `updated_at` and exact-ID confirmation checks. |
|
|
44
44
|
| `update_exercise` | write | Patch exercise fields with an `updated_at` precondition and shared-usage acknowledgement. |
|
|
45
45
|
| `set_exercise_visibility` | write | Make one writable exercise public or private when visibility controls are enabled. |
|
|
46
|
+
| `generate_exercise_translation_job` | write | Queue translation generation for one writable exercise. |
|
|
46
47
|
| `import_exercise` | write | Queue an exercise import from MCP files or HTTPS URLs. |
|
|
47
48
|
| `import_exercise_solution` | write | Queue a solution import for one exercise. |
|
|
48
49
|
| `search_sheets` | read | Search visible sheets, optionally by readiness issues. |
|
|
@@ -56,6 +57,7 @@ Treat write receipts as an agent audit log. They are suitable for user-visible s
|
|
|
56
57
|
| `update_sheet` | write | Patch sheet metadata with an `updated_at` precondition. |
|
|
57
58
|
| `set_sheet_visibility` | write | Make one writable sheet public or private when visibility controls are enabled. |
|
|
58
59
|
| `append_exercises_to_sheet` | write | Append existing visible exercises to the end of one writable sheet. |
|
|
60
|
+
| `generate_sheet_translation_job` | write | Queue translation generation for one writable exercise sheet. |
|
|
59
61
|
| `list_folders` | read | List sheet folders in the selected organization. |
|
|
60
62
|
| `create_folder` | write | Create a sheet folder. |
|
|
61
63
|
| `rename_folder` | write | Rename a sheet folder. |
|