@chalksurf/cli 0.2.1 → 0.2.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/docs/agents.md CHANGED
@@ -33,7 +33,7 @@ Prefer storing the token in the explicit agent profile for repeated Codex/CI run
33
33
  For agent-driven imports, always use:
34
34
 
35
35
  - `--manifest -` or a generated manifest file
36
- - `--wait` when the next step depends on completed imports
36
+ - `--wait` when the next step depends on parsed content being saved
37
37
  - `--json` so the response stays machine-readable
38
38
 
39
39
  Recommended invocation shape:
@@ -49,6 +49,7 @@ In `--json` mode:
49
49
  - stderr is reserved for unexpected runtime failures
50
50
 
51
51
  Wait-style failures still include a populated `result` payload, so agents can inspect partial outcomes on exit code `6` or `7`.
52
+ When an import requests translations, `--wait` waits for the import job only. Follow-up translation jobs are listed under each completed import job's `translationJobs`.
52
53
 
53
54
  ## Manifest Design
54
55
 
@@ -60,6 +61,8 @@ Why:
60
61
  - each logical source can carry a stable `sourceId`
61
62
  - sheet imports can group multiple source files into one resulting sheet
62
63
  - sheet imports carry `targetFolderPath`, `title`, and `translateTo` at the sheet level
64
+ - exercise imports can carry top-level `translateTo` for every imported exercise
65
+ - sheet solution imports can reconcile one or more solution files against all updatable exercises in one existing sheet
63
66
  - agents can correlate import results back to the discovered source set
64
67
 
65
68
  Use `sourceId` whenever a browsing step or upstream scraper already has a stable identifier:
@@ -98,6 +101,7 @@ Further reference:
98
101
  - [Sheet import schema](../schemas/sheet-import-manifest.schema.json)
99
102
  - [Exercise import schema](../schemas/exercise-import-manifest.schema.json)
100
103
  - [Exercise solution import schema](../schemas/exercise-solution-import-manifest.schema.json)
104
+ - [Exercise sheet solution import schema](../schemas/exercise-sheet-solution-import-manifest.schema.json)
101
105
 
102
106
  ## JSON Result Shape
103
107
 
@@ -120,6 +124,7 @@ Each job includes:
120
124
  - `sourceIndexes`
121
125
  - `sourceIds`
122
126
  - `status`
127
+ - `translationJobs` when requested translations were queued after import
123
128
 
124
129
  `summary` includes:
125
130
 
@@ -133,8 +138,9 @@ Each job includes:
133
138
  2. Filter them to the target scope.
134
139
  3. Build a manifest with stable `sourceId` values.
135
140
  4. Pipe the manifest into the CLI with `--wait --json`.
136
- 5. Inspect `ok`, `result.summary`, and `result.jobs`.
137
- 6. Retry only the failed or timed-out source set.
141
+ 5. Inspect `ok`, `result.summary`, `result.jobs`, and any nested `translationJobs`.
142
+ 6. Use `job list`, `job wait`, `sheet search`, and `exercise search` to verify the created resources or translation jobs when needed.
143
+ 7. Retry only the failed or timed-out source set.
138
144
 
139
145
  For example:
140
146
 
@@ -163,6 +169,54 @@ On success, the envelope looks like:
163
169
 
164
170
  On timeout or job failure, `ok` becomes `false`, `error.code` is stable, and `result` still contains the normalized import data needed for retries.
165
171
 
172
+ ## Verification Commands
173
+
174
+ Agents can inspect their own work without opening the web UI. Search commands default to `--ownership own`, which means the selected organization from `--organization`, `CHALKSURF_ORGANIZATION_ID`, or the active profile.
175
+
176
+ List recent jobs, including jobs the UI tray has already viewed or dismissed:
177
+
178
+ ```bash
179
+ chalksurf --profile prod-codex job list --include-viewed --include-dismissed --json
180
+ ```
181
+
182
+ Find failed import jobs for retry:
183
+
184
+ ```bash
185
+ chalksurf --profile prod-codex job list \
186
+ --status failed \
187
+ --type exercise_sheet_import \
188
+ --include-viewed \
189
+ --include-dismissed \
190
+ --json
191
+ ```
192
+
193
+ Verify an imported private sheet by title:
194
+
195
+ ```bash
196
+ chalksurf --profile prod-codex sheet search --text "OKTV 2014" --json
197
+ ```
198
+
199
+ Verify imported exercises by text. Text search requires an explicit language:
200
+
201
+ ```bash
202
+ chalksurf --profile prod-codex exercise search \
203
+ --text "binomial theorem" \
204
+ --language english \
205
+ --json
206
+ ```
207
+
208
+ Import solutions for an already imported sheet when the solution key is separate:
209
+
210
+ ```bash
211
+ chalksurf --profile prod-codex sheet import-solutions \
212
+ 00000000-0000-4000-8000-000000000001 \
213
+ ./solutions.pdf \
214
+ --wait \
215
+ --json
216
+ ```
217
+
218
+ Use `--ownership public` for public-library checks and `--ownership all` when the agent intentionally wants public results plus selected-organization results.
219
+
166
220
  ## Codex Workflow Example
167
221
 
168
222
  Target task:
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "organizationId": "org_123",
3
3
  "exerciseSheetId": "00000000-0000-4000-8000-000000000111",
4
+ "translateTo": ["english"],
4
5
  "wait": true,
5
6
  "sources": [
6
7
  {
@@ -0,0 +1,13 @@
1
+ {
2
+ "organizationId": "org_123",
3
+ "exerciseSheetId": "00000000-0000-4000-8000-000000000333",
4
+ "wait": true,
5
+ "sources": [
6
+ {
7
+ "sourceId": "problem-set-solutions",
8
+ "kind": "local",
9
+ "path": "./imports/problem-set-solutions.pdf",
10
+ "relativePath": "Solutions/problem-set-solutions.pdf"
11
+ }
12
+ ]
13
+ }
package/docs/manifest.md CHANGED
@@ -7,6 +7,7 @@ One manifest file is passed to exactly one command:
7
7
  - `chalksurf sheet import --manifest <path|->`
8
8
  - `chalksurf exercise import --manifest <path|->`
9
9
  - `chalksurf exercise import-solution --manifest <path|->`
10
+ - `chalksurf sheet import-solutions --manifest <path|->`
10
11
 
11
12
  Use `--manifest -` to pipe JSON on stdin.
12
13
 
@@ -17,9 +18,9 @@ Every manifest is a JSON object with these shared metadata fields:
17
18
  | Field | Type | Required | Notes |
18
19
  | --- | --- | --- | --- |
19
20
  | `organizationId` | string | no | Overrides the default organization for this invocation. |
20
- | `wait` | boolean | no | Behaves like `--wait`. The CLI also accepts `--wait`, which wins if set. |
21
+ | `wait` | boolean | no | Behaves like `--wait`. The CLI also accepts `--wait`, which wins if set. Requested translations run as follow-up jobs listed in the import result. |
21
22
 
22
- Every source object supports these common fields. For `sheet import`, sources appear inside `sheets[].sources[]`. For the exercise import commands, they appear in top-level `sources[]`.
23
+ Every source object supports these common fields. For `sheet import`, sources appear inside `sheets[].sources[]`. For the exercise import commands and `sheet import-solutions`, they appear in top-level `sources[]`.
23
24
 
24
25
  | Field | Type | Required | Notes |
25
26
  | --- | --- | --- | --- |
@@ -85,11 +86,12 @@ Top-level fields:
85
86
  | --- | --- | --- | --- |
86
87
  | `sources` | array | yes | One or more import sources. |
87
88
  | `exerciseSheetId` | string | no | Default target sheet for the imported exercises. Can still be overridden by `--sheet-id`. |
89
+ | `translateTo` | string[] | no | Target translation languages for every imported exercise. Must be unique and non-empty when present. |
88
90
 
89
91
  Per-source fields:
90
92
 
91
93
  - Only the common source fields are allowed.
92
- - `title` and `translateTo` are rejected for this command.
94
+ - `title` and source-level `translateTo` are rejected for this command.
93
95
 
94
96
  Canonical example:
95
97
 
@@ -115,12 +117,32 @@ Canonical example:
115
117
  - [docs/examples/exercise-solution-import-manifest.json](./examples/exercise-solution-import-manifest.json)
116
118
  - [schemas/exercise-solution-import-manifest.schema.json](../schemas/exercise-solution-import-manifest.schema.json)
117
119
 
120
+ ### Exercise Sheet Solution Import
121
+
122
+ Top-level fields:
123
+
124
+ | Field | Type | Required | Notes |
125
+ | --- | --- | --- | --- |
126
+ | `sources` | array | yes | One or more source files containing solutions for some or all exercises in the target sheet. |
127
+ | `exerciseSheetId` | string | no | Default target sheet for the imported solution files. The command still requires a sheet id overall, either here or positionally. |
128
+
129
+ Per-source fields:
130
+
131
+ - Only the common source fields are allowed.
132
+ - `title` and `translateTo` are rejected for this command.
133
+
134
+ Canonical example:
135
+
136
+ - [docs/examples/exercise-sheet-solution-import-manifest.json](./examples/exercise-sheet-solution-import-manifest.json)
137
+ - [schemas/exercise-sheet-solution-import-manifest.schema.json](../schemas/exercise-sheet-solution-import-manifest.schema.json)
138
+
118
139
  ## Validation Notes
119
140
 
120
141
  The CLI validates more than the JSON schema can express on its own:
121
142
 
122
143
  - `sourceId` values must be unique within one manifest.
123
144
  - Sheet import `translateTo` values must be unique within one sheet.
145
+ - Exercise import top-level `translateTo` values must be unique.
124
146
  - `relativePath` cannot be empty or contain `..`.
125
147
  - Sheet import `targetFolderPath` must be `null` or a normalized folder path without `.` or `..` segments.
126
148
  - `directory` imports must resolve to at least one file.
package/docs/manual.md CHANGED
@@ -72,7 +72,7 @@ Import one sheet and wait for the background job to finish:
72
72
  chalksurf sheet import ./fixtures/algebra.pdf --wait
73
73
  ```
74
74
 
75
- Import one sheet, override its title, and request an English translation during import:
75
+ Import one sheet, override its title, and request an English translation after import:
76
76
 
77
77
  ```bash
78
78
  chalksurf sheet import ./fixtures/algebra.pdf \
@@ -95,6 +95,7 @@ Import exercises into an existing sheet:
95
95
  ```bash
96
96
  chalksurf exercise import ./fixtures/problem-set.pdf \
97
97
  --sheet-id 00000000-0000-4000-8000-000000000001 \
98
+ --translate-to english \
98
99
  --wait
99
100
  ```
100
101
 
@@ -107,6 +108,15 @@ chalksurf exercise import-solution \
107
108
  --wait
108
109
  ```
109
110
 
111
+ Import a separate solution file for an existing exercise sheet:
112
+
113
+ ```bash
114
+ chalksurf sheet import-solutions \
115
+ 00000000-0000-4000-8000-000000000001 \
116
+ ./fixtures/sheet-solutions.pdf \
117
+ --wait
118
+ ```
119
+
110
120
  Import from a remote URL:
111
121
 
112
122
  ```bash
@@ -126,6 +136,18 @@ Sheet import manifests use top-level `sheets[]`. Each sheet has one destination
126
136
 
127
137
  ## Working With Jobs
128
138
 
139
+ List recent jobs:
140
+
141
+ ```bash
142
+ chalksurf job list
143
+ ```
144
+
145
+ Include jobs already viewed or dismissed in the web UI:
146
+
147
+ ```bash
148
+ chalksurf job list --include-viewed --include-dismissed
149
+ ```
150
+
129
151
  Read one job:
130
152
 
131
153
  ```bash
@@ -138,7 +160,29 @@ Wait on one or more jobs later:
138
160
  chalksurf job wait job_123 job_124
139
161
  ```
140
162
 
141
- `--wait` on an import command means the requested import work is complete before the command exits. For sheet imports, that includes requested translations.
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
+
165
+ ## Searching From The CLI
166
+
167
+ Search commands default to `--ownership own`, which means resources in the selected organization.
168
+
169
+ Find exercise sheets by title:
170
+
171
+ ```bash
172
+ chalksurf sheet search --text "OKTV 2014"
173
+ ```
174
+
175
+ Find exercises by text:
176
+
177
+ ```bash
178
+ chalksurf exercise search --text "binomial theorem" --language english
179
+ ```
180
+
181
+ Search public resources instead:
182
+
183
+ ```bash
184
+ chalksurf sheet search --text "OKTV" --ownership public
185
+ ```
142
186
 
143
187
  ## Troubleshooting
144
188
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chalksurf/cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -14,6 +14,14 @@
14
14
  "type": "string",
15
15
  "minLength": 1
16
16
  },
17
+ "translateTo": {
18
+ "type": "array",
19
+ "minItems": 1,
20
+ "uniqueItems": true,
21
+ "items": {
22
+ "$ref": "#/$defs/translateLanguage"
23
+ }
24
+ },
17
25
  "wait": {
18
26
  "type": "boolean"
19
27
  },
@@ -30,6 +38,10 @@
30
38
  "type": "string",
31
39
  "minLength": 1
32
40
  },
41
+ "translateLanguage": {
42
+ "type": "string",
43
+ "enum": ["english", "hungarian", "german", "french", "spanish", "italian"]
44
+ },
33
45
  "localSource": {
34
46
  "type": "object",
35
47
  "additionalProperties": false,
@@ -0,0 +1,104 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/knowledge-maps/chalksurf/blob/main/packages/cli/schemas/exercise-sheet-solution-import-manifest.schema.json",
4
+ "title": "ChalkSurf Exercise Sheet Solution Import Manifest",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["sources"],
8
+ "properties": {
9
+ "organizationId": {
10
+ "type": "string",
11
+ "minLength": 1
12
+ },
13
+ "exerciseSheetId": {
14
+ "type": "string",
15
+ "minLength": 1
16
+ },
17
+ "wait": {
18
+ "type": "boolean"
19
+ },
20
+ "sources": {
21
+ "type": "array",
22
+ "minItems": 1,
23
+ "items": {
24
+ "$ref": "#/$defs/source"
25
+ }
26
+ }
27
+ },
28
+ "$defs": {
29
+ "nonEmptyString": {
30
+ "type": "string",
31
+ "minLength": 1
32
+ },
33
+ "localSource": {
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": ["kind", "path"],
37
+ "properties": {
38
+ "sourceId": {
39
+ "$ref": "#/$defs/nonEmptyString"
40
+ },
41
+ "kind": {
42
+ "const": "local"
43
+ },
44
+ "path": {
45
+ "$ref": "#/$defs/nonEmptyString"
46
+ },
47
+ "relativePath": {
48
+ "$ref": "#/$defs/nonEmptyString"
49
+ }
50
+ }
51
+ },
52
+ "directorySource": {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "required": ["kind", "path"],
56
+ "properties": {
57
+ "sourceId": {
58
+ "$ref": "#/$defs/nonEmptyString"
59
+ },
60
+ "kind": {
61
+ "const": "directory"
62
+ },
63
+ "path": {
64
+ "$ref": "#/$defs/nonEmptyString"
65
+ },
66
+ "relativeRoot": {
67
+ "$ref": "#/$defs/nonEmptyString"
68
+ }
69
+ }
70
+ },
71
+ "urlSource": {
72
+ "type": "object",
73
+ "additionalProperties": false,
74
+ "required": ["kind", "url"],
75
+ "properties": {
76
+ "sourceId": {
77
+ "$ref": "#/$defs/nonEmptyString"
78
+ },
79
+ "kind": {
80
+ "const": "url"
81
+ },
82
+ "url": {
83
+ "$ref": "#/$defs/nonEmptyString"
84
+ },
85
+ "relativePath": {
86
+ "$ref": "#/$defs/nonEmptyString"
87
+ }
88
+ }
89
+ },
90
+ "source": {
91
+ "oneOf": [
92
+ {
93
+ "$ref": "#/$defs/localSource"
94
+ },
95
+ {
96
+ "$ref": "#/$defs/directorySource"
97
+ },
98
+ {
99
+ "$ref": "#/$defs/urlSource"
100
+ }
101
+ ]
102
+ }
103
+ }
104
+ }