@litfamily/lithermes 1.0.4 → 1.0.5

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.
Files changed (51) hide show
  1. package/README.md +101 -85
  2. package/README_Ko-KR.md +109 -95
  3. package/assets/lithermes-plugin/README.md +27 -17
  4. package/assets/lithermes-plugin/__init__.py +5 -1
  5. package/assets/lithermes-plugin/core_contexts.py +18 -4
  6. package/assets/lithermes-plugin/core_routing.py +2 -0
  7. package/assets/lithermes-plugin/diagnostics.py +48 -16
  8. package/assets/lithermes-plugin/payload-version.json +105 -13
  9. package/assets/lithermes-plugin/plugin.yaml +1 -1
  10. package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +11 -12
  11. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +24 -13
  12. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/default-editorial-pixel.json +18 -0
  13. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/operating-lanes.md +1 -1
  14. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/product-direction.md +1 -1
  15. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/production.md +13 -0
  16. package/assets/lithermes-plugin/skills/readme-studio/SKILL.md +73 -0
  17. package/assets/lithermes-plugin/skills/readme-studio/references/decoration-patterns.md +36 -0
  18. package/assets/lithermes-plugin/skills/readme-studio/references/facts.md +11 -0
  19. package/assets/lithermes-plugin/skills/readme-studio/references/motion.md +34 -0
  20. package/assets/lithermes-plugin/skills/readme-studio/references/production-interview.md +15 -0
  21. package/assets/lithermes-plugin/skills/readme-studio/references/type-and-images.md +17 -0
  22. package/assets/lithermes-plugin/skills/readme-studio/scripts/check_facts.py +103 -0
  23. package/assets/lithermes-plugin/skills/readme-studio/templates/cover-section.md +63 -0
  24. package/assets/lithermes-plugin/skills/readme-studio/templates/cover-settings.json +11 -0
  25. package/assets/lithermes-plugin/skills/readme-studio/templates/cover-source.json +12 -0
  26. package/assets/lithermes-plugin/skills/readme-studio/templates/facts.json +1 -0
  27. package/assets/lithermes-plugin/skills/readme-studio/templates/hyperframes/index.html +54 -0
  28. package/assets/lithermes-plugin/skills/readme-studio/templates/hyperframes/index.motion.json +1 -0
  29. package/assets/lithermes-plugin/skills/readme-studio/templates/hyperframes/package-lock.json +1843 -0
  30. package/assets/lithermes-plugin/skills/readme-studio/templates/hyperframes/package.json +6 -0
  31. package/assets/lithermes-plugin/skills/readme-studio/templates/remotion/package-lock.json +3783 -0
  32. package/assets/lithermes-plugin/skills/readme-studio/templates/remotion/package.json +7 -0
  33. package/assets/lithermes-plugin/skills/readme-studio/templates/remotion/src/index.tsx +34 -0
  34. package/assets/lithermes-plugin/skills/readme-studio/templates/typography/outline.mjs +79 -0
  35. package/assets/lithermes-plugin/skills/readme-studio/templates/typography/package-lock.json +133 -0
  36. package/assets/lithermes-plugin/skills/readme-studio/templates/typography/package.json +6 -0
  37. package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
  38. package/package.json +1 -1
  39. package/readme-assets/Lucide-LICENSE.txt +43 -0
  40. package/readme-assets/ascii-readme.svg +5 -0
  41. package/readme-assets/badge-version.svg +1 -1
  42. package/readme-assets/cover-motion-still.webp +0 -0
  43. package/readme-assets/cover-motion.webp +0 -0
  44. package/readme-assets/ignition-film.mp4 +0 -0
  45. package/readme-assets/lucide-book-open.svg +14 -0
  46. package/readme-assets/lucide-play.svg +13 -0
  47. package/readme-assets/lucide-shield-check.svg +14 -0
  48. package/src/lib/install.js +2 -1
  49. package/src/lib/modelConfig.js +11 -7
  50. package/src/lib/modelRoutePolicy.js +94 -51
  51. package/src/lib/skillPayload.js +1 -1
@@ -6,6 +6,7 @@ const { OPENAI_PROVIDER, RESPONSES_MODE, classifyHostVersion,
6
6
  const {
7
7
  ASTRA_MODEL,
8
8
  MANAGED_PROVIDER_MODELS,
9
+ MODEL_IDS,
9
10
  applyManagedRoute,
10
11
  customChildTransportReason,
11
12
  inspectEffectiveRouteSafety,
@@ -17,8 +18,6 @@ const {
17
18
  unavailableTuiRouteVisibility,
18
19
  } = require("./modelRoutePolicy");
19
20
 
20
- const MODELS = new Set(["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]);
21
-
22
21
  // The route every "configured" verdict is measured against: explicit installer
23
22
  // options win; otherwise the document's own route when it is a catalog route;
24
23
  // otherwise today's shipped default.
@@ -45,6 +44,12 @@ function expectedRoute(options = {}, document = null) {
45
44
  const SAFE_CONTEXT_LENGTH = 372000;
46
45
  const SAFE_COMPRESSION_THRESHOLD = 0.9;
47
46
  const SAFE_AUTO_COMPACTION_LIMIT = SAFE_CONTEXT_LENGTH * SAFE_COMPRESSION_THRESHOLD;
47
+ const LEGACY_CONTEXT_MODELS = new Set([
48
+ "gpt-5.6",
49
+ "gpt-5.6-sol",
50
+ "gpt-5.6-terra",
51
+ "gpt-5.6-luna",
52
+ ]);
48
53
  const MANAGED_SAMPLING_KEYS = ["temperature", "top_p", "top_logprobs"];
49
54
 
50
55
  function hasValue(document, path) {
@@ -156,7 +161,7 @@ function classificationFromDocument(document, fresh) {
156
161
  if (provider === OPENAI_PROVIDER && (dispatch === "gpt-5.4" || dispatch === "gpt-5.5")) {
157
162
  return { class: "managed_legacy", originalDispatchId };
158
163
  }
159
- if (provider === OPENAI_PROVIDER && MODELS.has(dispatch)) {
164
+ if (provider === OPENAI_PROVIDER && MODEL_IDS.has(dispatch)) {
160
165
  return { class: "existing_managed", originalDispatchId };
161
166
  }
162
167
  if (MANAGED_PROVIDER_MODELS[provider]?.has(dispatch)) {
@@ -364,10 +369,9 @@ function planModelConfig(text, options = {}) {
364
369
  }
365
370
  const document = boundary.document;
366
371
  applyManagedRoute(document, route);
367
- // The verified legacy context/compression defaults belong to legacy model
368
- // resets only. Astra has no host-published limit evidence, so an Astra reset
369
- // preserves explicit values and leaves missing values absent.
370
- if (options.reconfigure && route.model !== ASTRA_MODEL && route.childModel !== ASTRA_MODEL) {
372
+ // The verified context/compression defaults apply only to explicit GPT-5.6
373
+ // model resets. GPT-6 model routes have no published evidence for these limits.
374
+ if (options.reconfigure && LEGACY_CONTEXT_MODELS.has(route.model)) {
371
375
  document.setIn(["model", "context_length"], SAFE_CONTEXT_LENGTH);
372
376
  document.setIn(["compression", "threshold"], SAFE_COMPRESSION_THRESHOLD);
373
377
  }
@@ -1,38 +1,77 @@
1
1
  const ASTRA_MODEL = "gpt-6-astra";
2
- const ASTRA_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
2
+ const GPT6_LEAD_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max", "ultra"]);
3
+ const ASTRA_EFFORTS = GPT6_LEAD_EFFORTS;
3
4
  const PARENT_MODEL = ASTRA_MODEL;
4
5
  const PARENT_EFFORT = "xhigh";
5
- const CHILD_MODEL = "gpt-5.6-luna";
6
+ const SOL_MODEL = "gpt-6-sol";
7
+ const CHILD_MODEL = "gpt-6-luna";
8
+ const LEGACY_SOL_MODEL = "gpt-5.6-sol";
9
+ const LEGACY_CHILD_MODEL = "gpt-5.6-luna";
6
10
  const CHILD_EFFORT = "max";
7
- const LUNA_EFFORTS = new Set(["high", "max"]);
11
+ const GPT6_LUNA_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
12
+ const LEGACY_LUNA_EFFORTS = new Set(["high", "max"]);
13
+ const LUNA_EFFORTS = LEGACY_LUNA_EFFORTS;
14
+ const LUNA_MODELS = new Set([CHILD_MODEL, LEGACY_CHILD_MODEL]);
8
15
  const TERRA_MODEL = "gpt-5.6-terra";
9
16
  const TERRA_EFFORTS = new Set(["high", "xhigh", "max"]);
17
+ const LEGACY_SOL_EFFORTS = new Set(["high", "xhigh"]);
18
+ const MODEL_EFFORTS = new Map([
19
+ [ASTRA_MODEL, GPT6_LEAD_EFFORTS],
20
+ [SOL_MODEL, GPT6_LEAD_EFFORTS],
21
+ [CHILD_MODEL, GPT6_LUNA_EFFORTS],
22
+ [LEGACY_SOL_MODEL, LEGACY_SOL_EFFORTS],
23
+ [LEGACY_CHILD_MODEL, LEGACY_LUNA_EFFORTS],
24
+ ["gpt-5.6", new Set(["high"])],
25
+ [TERRA_MODEL, TERRA_EFFORTS],
26
+ ]);
10
27
  const CHILD_TRANSPORT_KEYS = ["provider", "base_url", "api_mode"];
11
28
  const { OPENAI_PROVIDER: OPENAI_PROVIDER_ID } = require("./modelConfigBoundary");
12
29
  const XAI_PROVIDER_ID = "xai";
13
30
  // Installer choice catalog (plans/references/installer-choice-contract.md, LitHermes row).
14
- // OpenAI rows: Astra exposes exactly the five Responses efforts; the existing Sol,
15
- // Luna, and general GPT-5.6 rows remain below it and Luna+xhigh is never listed. xAI rows: the
16
- // reasoning-capable models of the Hermes 0.19 static xAI catalog
31
+ // OpenAI rows follow each model's listed effort set, including selectable legacy
32
+ // GPT-5.6 routes. xAI rows use the reasoning-capable models of the Hermes 0.19 catalog
17
33
  // (hermes_cli/models.py `_XAI_STATIC_FALLBACK`), newest first, with the Hermes
18
34
  // reasoning_effort vocabulary (hermes_cli/config.py delegation.reasoning_effort).
19
35
  const ROUTE_CATALOG = {
20
36
  [OPENAI_PROVIDER_ID]: {
21
37
  credentialEnv: null,
22
- label: "OpenAI OAuth Responses (Astra + GPT-5.6)",
38
+ label: "OpenAI OAuth Responses (Astra + Sol + Luna)",
23
39
  rows: [
24
- ...["low", "medium", "high", "xhigh", "max"].map((effort) => ({
40
+ ...["low", "medium", "high", "xhigh", "max", "ultra"].map((effort) => ({
25
41
  effort,
26
42
  model: ASTRA_MODEL,
27
- note: effort === "max"
43
+ note: effort === "ultra"
28
44
  ? "deepest Astra reasoning"
29
45
  : effort === PARENT_EFFORT
30
46
  ? "recommended lead"
31
47
  : "Astra Responses effort",
32
48
  })),
33
- { effort: PARENT_EFFORT, model: "gpt-5.6-sol", note: "existing Sol lead route" },
34
- { effort: CHILD_EFFORT, model: CHILD_MODEL, note: "balanced (recommended helper)" },
35
- { effort: "high", model: CHILD_MODEL, note: "balanced, lighter effort" },
49
+ ...["low", "medium", "high", "xhigh", "max", "ultra"].map((effort) => ({
50
+ effort,
51
+ model: SOL_MODEL,
52
+ note: effort === PARENT_EFFORT ? "coding lead alternative" : "Sol Responses effort",
53
+ })),
54
+ ...["low", "medium", "high", "xhigh", "max"].map((effort) => ({
55
+ effort,
56
+ model: CHILD_MODEL,
57
+ note: effort === CHILD_EFFORT
58
+ ? "balanced (recommended helper)"
59
+ : effort === "high"
60
+ ? "balanced, lighter effort"
61
+ : "Luna Responses effort",
62
+ })),
63
+ ...["high", "xhigh"].map((effort) => ({
64
+ effort,
65
+ model: LEGACY_SOL_MODEL,
66
+ note: "previous-generation Sol lead route",
67
+ })),
68
+ ...["high", "xhigh", "max"].map((effort) => ({
69
+ effort,
70
+ model: TERRA_MODEL,
71
+ note: "previous-generation Terra route",
72
+ })),
73
+ { effort: CHILD_EFFORT, model: LEGACY_CHILD_MODEL, note: "previous-generation balanced helper" },
74
+ { effort: "high", model: LEGACY_CHILD_MODEL, note: "previous-generation lighter helper" },
36
75
  { effort: "high", model: "gpt-5.6", note: "general model" },
37
76
  ],
38
77
  lead: { effort: PARENT_EFFORT, model: PARENT_MODEL },
@@ -55,6 +94,10 @@ const PROVIDER_IDS = Object.keys(ROUTE_CATALOG);
55
94
  const MANAGED_PROVIDER_MODELS = Object.fromEntries(
56
95
  PROVIDER_IDS.map((id) => [id, new Set(ROUTE_CATALOG[id].rows.map((row) => row.model))]),
57
96
  );
97
+ const MODEL_IDS = new Set([
98
+ ...MANAGED_PROVIDER_MODELS[OPENAI_PROVIDER_ID],
99
+ TERRA_MODEL,
100
+ ]);
58
101
  const MANAGED_PROVIDERS = new Set(PROVIDER_IDS);
59
102
  const UNSAFE_ROUTE_CODE = "LITHERMES_UNSAFE_MODEL_ROUTE";
60
103
  const REVIEWER_ROUTE_NAME = String.fromCharCode(109, 111, 109, 117, 115);
@@ -83,42 +126,32 @@ function inspectEffectiveRouteSafety(document, expectedProvider) {
83
126
  const managedRoutes = routes.filter((route) => route.provider === expectedProvider);
84
127
  for (const route of managedRoutes) {
85
128
  if (transportReason && route.route === "global_child") continue;
86
- if (route.model === ASTRA_MODEL && !ASTRA_EFFORTS.has(route.effort)) {
87
- return {
88
- classificationClass: "astra_effort_unsupported",
89
- code: UNSAFE_ROUTE_CODE,
90
- observedSource: `${route.route} model, effort, and provider config`,
91
- reason: `${route.route} Astra effort is unsupported or missing; choose one of: ${[...ASTRA_EFFORTS].join(", ")}`,
92
- route: route.route,
93
- status: "blocked",
94
- };
95
- }
96
- if (route.model === CHILD_MODEL && route.effort === "xhigh") {
97
- return {
98
- classificationClass: "conflicting_luna_xhigh",
99
- code: UNSAFE_ROUTE_CODE,
100
- observedSource: `${route.route} model, effort, and provider config`,
101
- reason: `${route.route} Luna xhigh is a forbidden pair (Luna runs at high or max)`,
102
- route: route.route,
103
- status: "blocked",
104
- };
105
- }
106
- if (route.model === CHILD_MODEL && !LUNA_EFFORTS.has(route.effort)) {
107
- return {
108
- classificationClass: "luna_effort_below_high",
109
- code: UNSAFE_ROUTE_CODE,
110
- observedSource: `${route.route} model, effort, and provider config`,
111
- reason: `${route.route} Luna effort is below high or missing`,
112
- route: route.route,
113
- status: "blocked",
114
- };
115
- }
116
- if (route.model === TERRA_MODEL && !TERRA_EFFORTS.has(route.effort)) {
129
+ const modelEfforts = MODEL_EFFORTS.get(route.model);
130
+ if (modelEfforts && !modelEfforts.has(route.effort)) {
131
+ const isAstra = route.model === ASTRA_MODEL;
132
+ const isLuna = LUNA_MODELS.has(route.model);
133
+ const isLegacyLunaXhigh = route.model === LEGACY_CHILD_MODEL && route.effort === "xhigh";
117
134
  return {
118
- classificationClass: "terra_effort_below_high",
135
+ classificationClass: isAstra
136
+ ? "astra_effort_unsupported"
137
+ : isLegacyLunaXhigh
138
+ ? "conflicting_luna_xhigh"
139
+ : isLuna
140
+ ? "luna_effort_below_high"
141
+ : route.model === TERRA_MODEL
142
+ ? "terra_effort_below_high"
143
+ : "model_effort_unsupported",
119
144
  code: UNSAFE_ROUTE_CODE,
120
145
  observedSource: `${route.route} model, effort, and provider config`,
121
- reason: `${route.route} TERRA effort is below high or missing`,
146
+ reason: isAstra
147
+ ? `${route.route} Astra effort is unsupported or missing; choose one of: ${[...modelEfforts].join(", ")}`
148
+ : isLegacyLunaXhigh
149
+ ? `${route.route} Luna xhigh is a forbidden pair (legacy Luna runs at high or max)`
150
+ : isLuna
151
+ ? `${route.route} Luna effort is unsupported; choose one of: ${[...modelEfforts].join(", ")}`
152
+ : route.model === TERRA_MODEL
153
+ ? `${route.route} TERRA effort is below high or missing`
154
+ : `${route.route} ${route.model} effort is unsupported or missing; choose one of: ${[...modelEfforts].join(", ")}`,
122
155
  route: route.route,
123
156
  status: "blocked",
124
157
  };
@@ -140,7 +173,7 @@ function inspectEffectiveRouteSafety(document, expectedProvider) {
140
173
  }
141
174
  return {
142
175
  observedSource: "parent and global delegation model policy",
143
- reason: "no effective under-effort Luna or TERRA route is configured",
176
+ reason: "no effective model and effort pair outside the model catalog is configured",
144
177
  status: "safe",
145
178
  };
146
179
  }
@@ -162,8 +195,8 @@ function resolveRow(provider, role, model, effort) {
162
195
  const hasModel = model !== undefined;
163
196
  const hasEffort = effort !== undefined;
164
197
  const resolvedModel = hasModel ? String(model) : preset.model;
165
- if (resolvedModel === CHILD_MODEL && hasEffort && effort === "xhigh") {
166
- throw new Error(`${role} route ${CHILD_MODEL} xhigh is a forbidden pair; Luna runs at high or max`);
198
+ if (resolvedModel === LEGACY_CHILD_MODEL && hasEffort && effort === "xhigh") {
199
+ throw new Error(`${role} route ${resolvedModel} xhigh is a forbidden pair; legacy Luna runs at high or max`);
167
200
  }
168
201
  const rowsForModel = catalog.rows.filter((row) => row.model === resolvedModel);
169
202
  if (!rowsForModel.length) {
@@ -244,10 +277,10 @@ function inspectManagedRoute(document, expectedProvider, route = managedRequest(
244
277
  && childModel === route.childModel
245
278
  && childEffort === route.childEffort;
246
279
  const legacyConfigured = parentProvider === expectedProvider
247
- && parentModel === "gpt-5.6-luna"
280
+ && parentModel === LEGACY_CHILD_MODEL
248
281
  && parentEffort === "max"
249
- && childModel === CHILD_MODEL
250
- && LUNA_EFFORTS.has(childEffort);
282
+ && childModel === LEGACY_CHILD_MODEL
283
+ && LEGACY_LUNA_EFFORTS.has(childEffort);
251
284
  if (!configured && !legacyConfigured) {
252
285
  return {
253
286
  status: "unavailable",
@@ -359,8 +392,18 @@ function formatManagedRoute(route) {
359
392
  module.exports = {
360
393
  ASTRA_EFFORTS,
361
394
  ASTRA_MODEL,
395
+ CHILD_MODEL,
396
+ GPT6_LEAD_EFFORTS,
397
+ GPT6_LUNA_EFFORTS,
398
+ LEGACY_LUNA_EFFORTS,
399
+ LEGACY_CHILD_MODEL,
400
+ LEGACY_SOL_MODEL,
401
+ LUNA_EFFORTS,
402
+ LUNA_MODELS,
362
403
  MANAGED_PROVIDER_MODELS,
404
+ MODEL_IDS,
363
405
  OPENAI_PROVIDER_ID,
406
+ SOL_MODEL,
364
407
  PROVIDER_IDS,
365
408
  ROUTE_CATALOG,
366
409
  XAI_PROVIDER_ID,
@@ -16,7 +16,7 @@ const MAX_PAYLOAD_TOTAL_BYTES = 16 * 1024 * 1024;
16
16
  const requiredSkills = [
17
17
  "lit-burnoff-file", "autoconference", "autoresearch", "browser-drive", "comment-checker", "debugging",
18
18
  "deep-interview",
19
- "frontend-ui-ux", "lit-commit", "lit-crucible", "lit-init",
19
+ "frontend-ui-ux", "readme-studio", "lit-commit", "lit-crucible", "lit-init",
20
20
  "lit-korean", "lit-comprehend", "lit-handoff", "lit-plan", "lit-recap",
21
21
  "lit-scientific-visualization", "litgoal", "litresearch", "litwork", "lsp",
22
22
  "lsp-setup", "lit-code", "refactor", "lit-burnoff", "review-work",