Skills › HyperFrames › media-use › prefs.mjs
prefs.mjs
69 lines · skills/media-use/scripts/prefs.mjs at a595755
1#!/usr/bin/env node
2/**
3 * Remembered defaults CLI — the lightweight tier of HyperFrames user memory.
4 *
5 * node prefs.mjs get --hyperframes . [--json]
6 * Print the merged view (project `.media/preferences.json` over user
7 * `~/.media/preferences.json`), each key with its source and the receipt
8 * material (confirmed_in, updated_at).
9 *
10 * node prefs.mjs record --hyperframes . --key destination --value x-feed [--workflow <w>]
11 * Record one confirmed brief answer into the project tier; the same value
12 * confirmed in two different projects promotes the key to the user tier.
13 *
14 * Consumption rule (references/memory.md): a remembered value becomes the
15 * recommended option with a receipt — it never skips a question.
16 */
17import { parseArgs } from "node:util";
18import { mergedPreferences, recordPreference } from "./lib/prefs-store.mjs";
20const { values: args, positionals } = parseArgs({
21 options: {
22 hyperframes: { type: "string", default: "." },
23 key: { type: "string" },
24 value: { type: "string" },
25 workflow: { type: "string" },
26 json: { type: "boolean", default: false },
27 },
28 allowPositionals: true,
29});
31const verb = positionals[0];
33function fail(message) {
34 console.error(message);
35 process.exit(1);
36}
38if (verb === "get") {
39 const merged = mergedPreferences(args.hyperframes);
40 if (args.json) {
41 console.log(JSON.stringify(merged, null, 2));
42 } else if (Object.keys(merged).length === 0) {
43 console.log("no remembered preferences yet");
44 } else {
45 for (const [key, entry] of Object.entries(merged)) {
46 console.log(
47 `${key} = ${entry.value} (${entry.source}; confirmed in ${entry.confirmed_in.join(", ")})`,
48 );
49 }
50 }
51} else if (verb === "record") {
52 if (!args.key || !args.value) fail("record needs --key and --value");
53 try {
54 const result = recordPreference({
55 projectDir: args.hyperframes,
56 key: args.key,
57 value: args.value,
58 workflow: args.workflow,
59 });
60 const promotion = result.promoted ? "; promoted to user tier" : "";
61 console.log(`recorded ${result.key} = ${result.value} (project${promotion})`);
62 } catch (err) {
63 fail(err instanceof Error ? err.message : String(err));
64 }
65} else {
66 fail(
67 "usage: prefs.mjs <get|record> --hyperframes . [--key <k> --value <v> --workflow <w>] [--json]",
68 );
69}