@stemtrooper/learningcode 0.4.3 → 0.4.4
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 +5 -1
- package/bin/learningcode.mjs +4 -1
- package/lib/settings.mjs +42 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -171,6 +171,10 @@ learningcode --mode json # machine-readable output
|
|
|
171
171
|
The TLC brand theme and banner ship with the package, so there is nothing to
|
|
172
172
|
configure.
|
|
173
173
|
|
|
174
|
+
LearningCode suppresses Pi's built-in startup header so the TLC banner appears
|
|
175
|
+
without the Pi logo flashing first. Use `learningcode --verbose` to show Pi's
|
|
176
|
+
startup details and loaded-resource list as well.
|
|
177
|
+
|
|
174
178
|
```
|
|
175
179
|
██╗ ███████╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗
|
|
176
180
|
██║ ██╔════╝██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
|
|
@@ -297,4 +301,4 @@ is also MIT. See [LICENSE](LICENSE).
|
|
|
297
301
|
|
|
298
302
|
Not affiliated with, endorsed by, or connected to Pi, OpenCode, Anomaly, or any of
|
|
299
303
|
the model providers reachable through this client. "The Learning Curve", TLC and
|
|
300
|
-
Spark are trademarks of The Learning Curve.
|
|
304
|
+
Spark are trademarks of The Learning Curve.
|
package/bin/learningcode.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "../lib/config.mjs";
|
|
18
18
|
import { GO_PROVIDER, saveProviderKey } from "../lib/auth.mjs";
|
|
19
19
|
import { ensureSparkProvider, modelsPath, retargetProvider } from "../lib/models.mjs";
|
|
20
|
+
import { ensureQuietStartup } from "../lib/settings.mjs";
|
|
20
21
|
import { ensureThemes, preferredTheme } from "../lib/themes.mjs";
|
|
21
22
|
import { hasToken, looksLikeToken, resolveToken, writeCachedToken } from "../lib/token.mjs";
|
|
22
23
|
|
|
@@ -45,6 +46,7 @@ Everything else is passed straight through to Pi, so the usual flags work:
|
|
|
45
46
|
learningcode -p "explain main.py" one-shot, non-interactive
|
|
46
47
|
learningcode --mode json machine-readable event stream
|
|
47
48
|
learningcode --list-models every model Pi can reach
|
|
49
|
+
learningcode --verbose show Pi's startup header and resource list
|
|
48
50
|
|
|
49
51
|
Other providers
|
|
50
52
|
Any --model other than tlc-spark/... skips the Spark token and the Spark
|
|
@@ -230,6 +232,7 @@ async function main() {
|
|
|
230
232
|
}
|
|
231
233
|
await ensureSparkProvider(dir);
|
|
232
234
|
await ensureThemes(dir);
|
|
235
|
+
await ensureQuietStartup(dir);
|
|
233
236
|
|
|
234
237
|
// `--login` forces a fresh paste even when a token is already cached.
|
|
235
238
|
const forced = [];
|
|
@@ -369,4 +372,4 @@ main().catch((error) => {
|
|
|
369
372
|
// Anything the user can act on gets one line. A stack trace is noise for a
|
|
370
373
|
// student who mistyped a token; keep it for genuine bugs.
|
|
371
374
|
fail(error instanceof UserError ? error.message : error?.stack || String(error));
|
|
372
|
-
});
|
|
375
|
+
});
|
package/lib/settings.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { UserError } from "./config.mjs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Pi renders its built-in header before extension `session_start` handlers run.
|
|
7
|
+
* Its supported quietStartup setting prevents that header flashing before the
|
|
8
|
+
* LearningCode banner is installed. Only seed the setting when it is unset, so
|
|
9
|
+
* an explicit choice in the student's LearningCode settings remains theirs.
|
|
10
|
+
*/
|
|
11
|
+
export async function ensureQuietStartup(agentDir) {
|
|
12
|
+
const path = join(agentDir, "settings.json");
|
|
13
|
+
let settings;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const contents = await readFile(path, "utf-8");
|
|
17
|
+
try {
|
|
18
|
+
settings = JSON.parse(contents.replace(/^\uFEFF/, ""));
|
|
19
|
+
} catch (error) {
|
|
20
|
+
throw new UserError(`Could not parse Pi settings at ${path}: ${error.message}`);
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error instanceof UserError) throw error;
|
|
24
|
+
if (error?.code !== "ENOENT") {
|
|
25
|
+
throw new UserError(`Could not read Pi settings at ${path}: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
settings = {};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!settings || typeof settings !== "object" || Array.isArray(settings)) {
|
|
31
|
+
throw new UserError(`Pi settings at ${path} must contain a JSON object.`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (typeof settings.quietStartup === "boolean" || settings.quietStartup === "header") {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
settings.quietStartup = true;
|
|
39
|
+
await mkdir(agentDir, { recursive: true });
|
|
40
|
+
await writeFile(path, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
41
|
+
return true;
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stemtrooper/learningcode",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "TLC Spark coding agent for students: Pi wired to the Spark OpenAI-compatible endpoint with per-student tokens, quota and seat-queue awareness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
8
|
-
"learningcode": "
|
|
8
|
+
"learningcode": "bin/learningcode.mjs"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"assets",
|