@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/README.md +14 -13
- package/dist/bin/chalksurf.js +3 -3
- package/dist/commands/exercise.js +178 -6
- package/dist/commands/job.js +108 -40
- package/dist/commands/sheet.js +323 -29
- package/dist/lib/api-client.js +11 -2
- package/dist/lib/command-options.js +61 -0
- package/dist/lib/import-output.js +14 -0
- package/dist/lib/manifest.js +24 -0
- package/dist/lib/session.js +27 -0
- package/dist/lib/translation-languages.js +15 -0
- package/dist/lib/user-jobs.js +6 -0
- package/docs/agents.md +57 -3
- package/docs/examples/exercise-import-manifest.json +1 -0
- package/docs/examples/exercise-sheet-solution-import-manifest.json +13 -0
- package/docs/manifest.md +25 -3
- package/docs/manual.md +46 -2
- package/package.json +1 -1
- package/schemas/exercise-import-manifest.schema.json +12 -0
- package/schemas/exercise-sheet-solution-import-manifest.schema.json +104 -0
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
|
|
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`,
|
|
137
|
-
6.
|
|
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:
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
@@ -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
|
+
}
|