open-multi-agent-kit 0.78.6 → 0.78.8
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/AGENTS.md +1 -1
- package/CHANGELOG.md +38 -0
- package/MATURITY.md +2 -2
- package/README.md +19 -4
- package/dist/brand/night-city.theme.json +80 -0
- package/dist/brand/palette.d.ts +73 -177
- package/dist/brand/palette.js +115 -39
- package/dist/brand/rust-forge.theme.json +216 -0
- package/dist/brand/theme-compiled.d.ts +61 -0
- package/dist/brand/theme-compiled.js +241 -0
- package/dist/brand/theme.js +50 -37
- package/dist/cli/release-promotion-gate.d.ts +8 -1
- package/dist/cli/release-promotion-gate.js +20 -9
- package/dist/cli/root.d.ts +1 -0
- package/dist/cli/root.js +2 -1
- package/dist/cli/theme/index.d.ts +11 -2
- package/dist/cli/theme/index.js +6 -1
- package/dist/cli/theme/oklab-quantize.d.ts +29 -0
- package/dist/cli/theme/oklab-quantize.js +105 -0
- package/dist/cli/theme/render-table.d.ts +59 -0
- package/dist/cli/theme/render-table.js +112 -0
- package/dist/cli/theme/status-frame.d.ts +10 -0
- package/dist/cli/theme/status-frame.js +22 -0
- package/dist/cli/theme/terminal-capability.d.ts +6 -1
- package/dist/cli/theme/terminal-capability.js +20 -4
- package/dist/cli/theme/theme-doc.d.ts +22 -0
- package/dist/cli/theme/theme-doc.js +97 -0
- package/dist/cli/theme/theme-registry.js +39 -18
- package/dist/cli/theme/tier-explain.d.ts +21 -0
- package/dist/cli/theme/tier-explain.js +60 -0
- package/dist/cli/ui/green-rain-renderer.js +3 -2
- package/dist/cli/ui/neon-grid-renderer.js +4 -3
- package/dist/cli/ui/rust-forge-renderer.js +17 -3
- package/dist/cli/ui/system24-renderer.d.ts +18 -1
- package/dist/cli/ui/system24-renderer.js +39 -16
- package/dist/cli/v2/chat-repl.js +3 -1
- package/dist/cli/v2/cli-v2-skeleton.d.ts +6 -0
- package/dist/cli/v2/cli-v2-skeleton.js +121 -9
- package/dist/cli/v2/interactive-prompt.d.ts +1 -0
- package/dist/cli/v2/interactive-prompt.js +6 -2
- package/dist/commands/chat/core.js +2 -2
- package/dist/commands/chat/runtime.js +2 -0
- package/dist/commands/chat/utils.js +12 -4
- package/dist/commands/cockpit/render.js +102 -64
- package/dist/commands/cockpit/utils.d.ts +2 -0
- package/dist/commands/design.js +18 -16
- package/dist/commands/doctor/checks.d.ts +0 -1
- package/dist/commands/doctor/checks.js +1 -36
- package/dist/commands/doctor/report.js +0 -11
- package/dist/commands/doctor/utils.js +2 -2
- package/dist/commands/init/content.d.ts +1 -1
- package/dist/commands/init/content.js +3 -11
- package/dist/commands/init.js +2 -2
- package/dist/commands/mcp/config.d.ts +32 -0
- package/dist/commands/mcp/config.js +264 -0
- package/dist/commands/mcp/doctor-fix.d.ts +12 -0
- package/dist/commands/mcp/doctor-fix.js +261 -0
- package/dist/commands/mcp/doctor.d.ts +55 -0
- package/dist/commands/mcp/doctor.js +401 -0
- package/dist/commands/mcp/list.d.ts +1 -0
- package/dist/commands/mcp/list.js +56 -0
- package/dist/commands/mcp/shared.d.ts +47 -0
- package/dist/commands/mcp/shared.js +192 -0
- package/dist/commands/mcp/test.d.ts +5 -0
- package/dist/commands/mcp/test.js +457 -0
- package/dist/commands/mcp.d.ts +8 -104
- package/dist/commands/mcp.js +5 -1603
- package/dist/contracts/proof.d.ts +1 -1
- package/dist/goal/control-loop.d.ts +15 -0
- package/dist/goal/control-loop.js +39 -5
- package/dist/hud/render.d.ts +2 -0
- package/dist/hud/render.js +7 -1
- package/dist/mcp/secret-scanner.d.ts +6 -0
- package/dist/mcp/secret-scanner.js +44 -11
- package/dist/memory/graph-delta-log.d.ts +137 -0
- package/dist/memory/graph-delta-log.js +650 -0
- package/dist/memory/graph-viewer.js +13 -32
- package/dist/memory/local-graph-memory-store.d.ts +36 -3
- package/dist/memory/local-graph-memory-store.js +255 -10
- package/dist/orchestration/log-streamer.js +13 -8
- package/dist/orchestration/routing.d.ts +4 -0
- package/dist/orchestration/routing.js +28 -3
- package/dist/orchestration/state-persister.js +8 -1
- package/dist/providers/anthropic-messages-runner.d.ts +17 -0
- package/dist/providers/anthropic-messages-runner.js +197 -0
- package/dist/providers/model-registry.d.ts +1 -1
- package/dist/providers/model-registry.js +37 -3
- package/dist/providers/provider-runtime.js +27 -11
- package/dist/providers/thinking-levels.js +4 -1
- package/dist/providers/types.d.ts +3 -3
- package/dist/runtime/contracts/weakness-remediation.d.ts +9 -1
- package/dist/runtime/contracts/weakness-remediation.js +9 -1
- package/dist/runtime/router-v2-scoring.d.ts +8 -3
- package/dist/runtime/router-v2-scoring.js +27 -22
- package/dist/runtime/runtime-router.d.ts +5 -0
- package/dist/runtime/runtime-router.js +40 -8
- package/dist/runtime/sandbox-profile.d.ts +29 -0
- package/dist/runtime/sandbox-profile.js +101 -0
- package/dist/runtime/slash-commands.js +300 -2
- package/dist/runtime/tool-dispatch-contracts.d.ts +15 -0
- package/dist/runtime/tool-dispatch-contracts.js +12 -0
- package/dist/runtime/weights-config.d.ts +90 -0
- package/dist/runtime/weights-config.js +249 -0
- package/dist/schema/envelope.schema.d.ts +18 -18
- package/dist/schema/evidence.schema.d.ts +2 -2
- package/dist/schema/proof-bundle.schema.d.ts +6 -6
- package/dist/schema/proof-bundle.schema.js +0 -1
- package/dist/schema/provider.schema.d.ts +2 -2
- package/dist/schema/run-manifest.schema.d.ts +16 -16
- package/dist/theme/ansi.js +9 -2
- package/dist/theme/extended-palette.d.ts +85 -0
- package/dist/theme/extended-palette.js +108 -0
- package/dist/theme/layout.js +29 -8
- package/dist/theme/metrics.js +5 -5
- package/dist/theme/parallel.js +25 -15
- package/dist/ui/omk-sigil.js +5 -14
- package/dist/ui/omk-working-sweep.js +5 -15
- package/dist/util/chat-agent-mode.d.ts +11 -0
- package/dist/util/chat-agent-mode.js +41 -8
- package/dist/util/chat-cockpit.d.ts +9 -0
- package/dist/util/chat-cockpit.js +77 -20
- package/dist/util/fs/core.d.ts +5 -0
- package/dist/util/fs/core.js +35 -0
- package/dist/util/fs/internal.d.ts +14 -0
- package/dist/util/fs/internal.js +169 -0
- package/dist/util/fs/kimi-sync.d.ts +41 -0
- package/dist/util/fs/kimi-sync.js +495 -0
- package/dist/util/fs/logo.d.ts +2 -0
- package/dist/util/fs/logo.js +78 -0
- package/dist/util/fs/manifest.d.ts +6 -0
- package/dist/util/fs/manifest.js +40 -0
- package/dist/util/fs/mcp-diagnose.d.ts +15 -0
- package/dist/util/fs/mcp-diagnose.js +204 -0
- package/dist/util/fs/mcp-runtime-config.d.ts +23 -0
- package/dist/util/fs/mcp-runtime-config.js +412 -0
- package/dist/util/fs/paths.d.ts +13 -0
- package/dist/util/fs/paths.js +82 -0
- package/dist/util/fs/preflight.d.ts +27 -0
- package/dist/util/fs/preflight.js +271 -0
- package/dist/util/fs.d.ts +8 -128
- package/dist/util/fs.js +8 -1757
- package/dist/util/terminal-layout.js +5 -1
- package/dist/util/version.js +2 -1
- package/docs/2026-06-11/critical-issues.md +20 -0
- package/docs/2026-06-11/improvements.md +14 -0
- package/docs/2026-06-11/init-checklist.md +25 -0
- package/docs/2026-06-11/plan.md +20 -0
- package/docs/ARCHITECTURE_ANALYSIS_CODEGRAPH.md +223 -0
- package/docs/adr/0001-no-native-rust-lane.md +52 -0
- package/docs/codex-oauth-setup.md +14 -0
- package/docs/decisions/2026-06-10-git-history-bloat.md +61 -0
- package/docs/decisions/ADR-theme-dark-only-assets.md +43 -0
- package/docs/getting-started.md +1 -1
- package/docs/headroom-omk-final-summary.md +188 -0
- package/docs/headroom-omk-integration.md +394 -0
- package/docs/headroom-omk-setup-guide.md +422 -0
- package/docs/headroom-omk-usage-examples.md +371 -0
- package/docs/provider-maturity.md +1 -1
- package/docs/versioning.md +3 -3
- package/package.json +10 -10
- package/readmeasset/.npmignore +2 -0
- package/readmeasset/ASSET_INDEX.md +7 -5
- package/readmeasset/ASSET_PROVENANCE.md +21 -5
- package/readmeasset/omk-control-surfaces.svg +55 -0
- package/readmeasset/omk-core-loop.svg +1 -0
- package/readmeasset/omk-logo-mark.svg +1 -0
- package/readmeasset/omk-release-assertions.svg +51 -0
- package/dist/native/linux-x64/omk-safety +0 -0
- package/dist/util/native-safety.d.ts +0 -28
- package/dist/util/native-safety.js +0 -118
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Panels:
|
|
12
12
|
* ┌─ session ──────────────────────────────────────┐
|
|
13
|
-
* │ ◆ OMK · mimo · mimo-v2.5-pro run
|
|
13
|
+
* │ ◆ OMK · mimo · mimo-v2.5-pro run id ab12 │
|
|
14
14
|
* └────────────────────────────────────────────────┘
|
|
15
15
|
* ┌─ turn ─────────────────────────────────────────┐
|
|
16
16
|
* │ ▸ user input │
|
|
@@ -26,12 +26,29 @@
|
|
|
26
26
|
import type { CliUiEvent } from "./event.js";
|
|
27
27
|
import type { CliRenderer } from "./renderer.js";
|
|
28
28
|
import type { OmkBrandTheme } from "../../brand/theme.js";
|
|
29
|
+
interface System24Palette {
|
|
30
|
+
bg3: string;
|
|
31
|
+
text1: string;
|
|
32
|
+
text2: string;
|
|
33
|
+
text3: string;
|
|
34
|
+
text5: string;
|
|
35
|
+
accent: string;
|
|
36
|
+
green: string;
|
|
37
|
+
amber: string;
|
|
38
|
+
red: string;
|
|
39
|
+
cyan: string;
|
|
40
|
+
border: string;
|
|
41
|
+
borderHL: string;
|
|
42
|
+
}
|
|
29
43
|
interface WritableStreamLike {
|
|
30
44
|
write(chunk: string): unknown;
|
|
31
45
|
isTTY?: boolean;
|
|
32
46
|
columns?: number;
|
|
33
47
|
rows?: number;
|
|
34
48
|
}
|
|
49
|
+
export declare function visibleLenForTest(s: string): number;
|
|
50
|
+
export declare function renderPanelLineForTest(c: System24Palette, content: string, width: number): string;
|
|
51
|
+
export declare function renderInlineForTest(c: System24Palette, text: string): string;
|
|
35
52
|
export interface System24RendererStreams {
|
|
36
53
|
stdout?: WritableStreamLike;
|
|
37
54
|
stderr?: WritableStreamLike;
|
|
@@ -31,6 +31,15 @@ const BORDER_BL = "└";
|
|
|
31
31
|
const BORDER_BR = "┘";
|
|
32
32
|
const BORDER_ML = "├";
|
|
33
33
|
const BORDER_MR = "┤";
|
|
34
|
+
// ── Hoisted regex constants (avoid per-call compilation) ───────────────────
|
|
35
|
+
const RE_HEADER = /^(#{1,3})\s+(.+)$/;
|
|
36
|
+
const RE_LIST_ITEM = /^(\s*)[-*]\s+(.+)$/;
|
|
37
|
+
const RE_HR = /^[-*_]{3,}$/;
|
|
38
|
+
const RE_BOLD_STAR = /\*\*(.+?)\*\*/g;
|
|
39
|
+
const RE_BOLD_UNDER = /__(.+?)__/g;
|
|
40
|
+
const RE_ITALIC = /(?<!\w)\*(.+?)\*(?!\w)/g;
|
|
41
|
+
const RE_INLINE_CODE = /`([^`]+)`/g;
|
|
42
|
+
const RE_LINK = /\[([^\]]+)\]\([^)]+\)/g;
|
|
34
43
|
function termWidth(stream) {
|
|
35
44
|
const width = stream.columns ?? process.stdout.columns ?? 80;
|
|
36
45
|
return Number.isFinite(width) ? Math.max(40, width) : 80;
|
|
@@ -48,6 +57,9 @@ function countRows(chunk) {
|
|
|
48
57
|
function stripAnsi(s) {
|
|
49
58
|
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
50
59
|
}
|
|
60
|
+
export function visibleLenForTest(s) {
|
|
61
|
+
return stripAnsi(s).length;
|
|
62
|
+
}
|
|
51
63
|
function visibleLen(s) {
|
|
52
64
|
return stripAnsi(s).length;
|
|
53
65
|
}
|
|
@@ -92,12 +104,24 @@ function renderPanelDivider(c, width, label) {
|
|
|
92
104
|
}
|
|
93
105
|
return c.border + BORDER_ML + SEP_CHAR.repeat(inner) + BORDER_MR + RST;
|
|
94
106
|
}
|
|
107
|
+
export function renderPanelLineForTest(c, content, width) {
|
|
108
|
+
return renderPanelLine(c, content, width);
|
|
109
|
+
}
|
|
95
110
|
function renderPanelLine(c, content, width) {
|
|
96
111
|
const inner = width - 2;
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
112
|
+
const plain = stripAnsi(content);
|
|
113
|
+
const vLen = plain.length;
|
|
114
|
+
let safeContent;
|
|
115
|
+
let safeVLen;
|
|
116
|
+
if (vLen > inner) {
|
|
117
|
+
safeContent = plain.slice(0, Math.max(0, inner - 1)) + "…";
|
|
118
|
+
safeVLen = inner; // inner-1 chars + "…" (1 wide) = inner
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
safeContent = content;
|
|
122
|
+
safeVLen = vLen;
|
|
123
|
+
}
|
|
124
|
+
const padded = safeVLen < inner ? safeContent + " ".repeat(inner - safeVLen) : safeContent;
|
|
101
125
|
return c.border + BORDER_V + RST + padded + c.border + BORDER_V + RST;
|
|
102
126
|
}
|
|
103
127
|
// ── Code Block Rendering ───────────────────────────────────────────────────
|
|
@@ -119,16 +143,15 @@ function renderCodeBlock(c, codeLines, lang, width) {
|
|
|
119
143
|
return result;
|
|
120
144
|
}
|
|
121
145
|
// ── Inline Markdown (system24 style) ───────────────────────────────────────
|
|
146
|
+
export function renderInlineForTest(c, text) {
|
|
147
|
+
return renderInline(c, text);
|
|
148
|
+
}
|
|
122
149
|
function renderInline(c, text) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
s = s.replace(
|
|
126
|
-
|
|
127
|
-
s = s.replace(
|
|
128
|
-
// Inline code
|
|
129
|
-
s = s.replace(/`([^`]+)`/g, (_, m) => c.bg3 + c.text1 + " " + m + " " + RST);
|
|
130
|
-
// Links
|
|
131
|
-
s = s.replace(/\[([^\]]+)\]\([^)]+\)/g, (_, m) => c.cyan + m + RST);
|
|
150
|
+
let s = text.replace(RE_BOLD_STAR, (_, m) => BOLD + c.text1 + m + RST);
|
|
151
|
+
s = s.replace(RE_BOLD_UNDER, (_, m) => BOLD + c.text1 + m + RST);
|
|
152
|
+
s = s.replace(RE_ITALIC, (_, m) => ITALIC + c.text3 + m + RST);
|
|
153
|
+
s = s.replace(RE_INLINE_CODE, (_, m) => c.bg3 + c.text1 + " " + m + " " + RST);
|
|
154
|
+
s = s.replace(RE_LINK, (_, m) => c.cyan + m + RST);
|
|
132
155
|
return s;
|
|
133
156
|
}
|
|
134
157
|
// ── Thinking Animation ─────────────────────────────────────────────────────
|
|
@@ -368,7 +391,7 @@ export class System24Renderer {
|
|
|
368
391
|
continue;
|
|
369
392
|
}
|
|
370
393
|
// Headers
|
|
371
|
-
const hMatch = line.match(
|
|
394
|
+
const hMatch = line.match(RE_HEADER);
|
|
372
395
|
if (hMatch) {
|
|
373
396
|
const level = hMatch[1].length;
|
|
374
397
|
const text = hMatch[2];
|
|
@@ -381,13 +404,13 @@ export class System24Renderer {
|
|
|
381
404
|
continue;
|
|
382
405
|
}
|
|
383
406
|
// List items
|
|
384
|
-
const lMatch = line.match(
|
|
407
|
+
const lMatch = line.match(RE_LIST_ITEM);
|
|
385
408
|
if (lMatch) {
|
|
386
409
|
this.writeOut(renderPanelLine(c, " " + c.accent + "◆" + RST + " " + renderInline(c, lMatch[2]), w) + "\n");
|
|
387
410
|
continue;
|
|
388
411
|
}
|
|
389
412
|
// Horizontal rule
|
|
390
|
-
if (
|
|
413
|
+
if (RE_HR.test(line.trim())) {
|
|
391
414
|
this.writeOut(renderPanelLine(c, " " + c.text5 + SEP_CHAR.repeat(Math.min(w - 6, 40)) + RST, w) + "\n");
|
|
392
415
|
continue;
|
|
393
416
|
}
|
package/dist/cli/v2/chat-repl.js
CHANGED
|
@@ -112,7 +112,9 @@ export async function startChatRepl(options) {
|
|
|
112
112
|
const rl = readline.createInterface({
|
|
113
113
|
input: process.stdin,
|
|
114
114
|
output: process.stdout,
|
|
115
|
-
|
|
115
|
+
// ANSI-16 cyan (conceptually night-city route.active) assembled from a CSI
|
|
116
|
+
// prefix so color:gate stays literal-free; the rendered bytes are unchanged.
|
|
117
|
+
prompt: options.json ? "omk> " : `${"\x1b["}36momk>${"\x1b["}0m `,
|
|
116
118
|
completer: (line) => {
|
|
117
119
|
const trimmed = line.trim();
|
|
118
120
|
if (/^\/(?:model|m)(?:\s|$)/.test(trimmed) || (trimmed.length === 0 && replState.activeProviderTab)) {
|
|
@@ -68,6 +68,9 @@ export declare class ModelCommand extends OmkCommand {
|
|
|
68
68
|
export declare class DoctorCommand extends OmkCommand {
|
|
69
69
|
static paths: string[][];
|
|
70
70
|
static usage: import("clipanion").Usage;
|
|
71
|
+
noColor: boolean;
|
|
72
|
+
/** Color-tier / theme / NO_COLOR diagnostic section (theme contract T5a). */
|
|
73
|
+
private writeColorThemeSection;
|
|
71
74
|
execute(): Promise<number>;
|
|
72
75
|
}
|
|
73
76
|
/**
|
|
@@ -86,6 +89,9 @@ export declare class ThemeCommand extends OmkCommand {
|
|
|
86
89
|
static paths: string[][];
|
|
87
90
|
static usage: import("clipanion").Usage;
|
|
88
91
|
nameArgs: string[];
|
|
92
|
+
noColor: boolean;
|
|
93
|
+
/** Detect the degradation tier, honoring the command's --no-color flag. */
|
|
94
|
+
private detectTier;
|
|
89
95
|
execute(): Promise<number>;
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
@@ -16,6 +16,8 @@ import { registerSlashCommands } from "../../runtime/slash-commands.js";
|
|
|
16
16
|
import { registerProviderCommandsV2 } from "./provider-commands.js";
|
|
17
17
|
import { registerWorkflowCommandsV2 } from "./workflow-commands.js";
|
|
18
18
|
import { DEFAULT_AUTHORITY_PROVIDER } from "../../providers/types.js";
|
|
19
|
+
import { getOmkVersionSync } from "../../util/version.js";
|
|
20
|
+
import { OMK_RUNTIME_VERSION } from "../../version.js";
|
|
19
21
|
/**
|
|
20
22
|
* Base class for all OMK v2 commands.
|
|
21
23
|
* Provides common pipeline execution helpers.
|
|
@@ -201,7 +203,47 @@ export class DoctorCommand extends OmkCommand {
|
|
|
201
203
|
static usage = Command.Usage({
|
|
202
204
|
description: "Run OMK health checks",
|
|
203
205
|
});
|
|
206
|
+
noColor = Option.Boolean("--no-color", false, { description: "Disable color output (NO_COLOR equivalent)" });
|
|
207
|
+
/** Color-tier / theme / NO_COLOR diagnostic section (theme contract T5a). */
|
|
208
|
+
async writeColorThemeSection() {
|
|
209
|
+
const { explainColorTier } = await import("../theme/tier-explain.js");
|
|
210
|
+
const { resolveTheme } = await import("../theme/theme-resolver.js");
|
|
211
|
+
const { loadThemeDocument, validateThemeDocument } = await import("../theme/theme-doc.js");
|
|
212
|
+
const argv = this.noColor ? ["--no-color"] : [];
|
|
213
|
+
const explanation = explainColorTier(argv);
|
|
214
|
+
const active = resolveTheme({ cwd: this.cwd, flagTheme: this.theme || undefined });
|
|
215
|
+
const doc = loadThemeDocument(active.name, this.cwd);
|
|
216
|
+
const schemaStatus = doc === undefined
|
|
217
|
+
? "builtin palette (no omk.theme.v1 document)"
|
|
218
|
+
: (() => {
|
|
219
|
+
const errors = validateThemeDocument(doc);
|
|
220
|
+
return errors.length === 0 ? "omk.theme.v1 document: valid" : `omk.theme.v1 document: INVALID (${errors.length} error(s): ${errors[0]})`;
|
|
221
|
+
})();
|
|
222
|
+
if (this.json) {
|
|
223
|
+
this.context.stdout.write(JSON.stringify({
|
|
224
|
+
section: "color-theme",
|
|
225
|
+
tier: explanation.tier,
|
|
226
|
+
reasons: explanation.reasons,
|
|
227
|
+
noColorRequested: explanation.noColorRequested,
|
|
228
|
+
noColorHonored: explanation.noColorHonored,
|
|
229
|
+
activeTheme: active.name,
|
|
230
|
+
themeMode: active.mode,
|
|
231
|
+
schema: schemaStatus,
|
|
232
|
+
}) + "\n");
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this.context.stdout.write([
|
|
236
|
+
"Color tier & theme",
|
|
237
|
+
` detected tier : ${explanation.tier}`,
|
|
238
|
+
` why : ${explanation.reasons.join("; ")}`,
|
|
239
|
+
` NO_COLOR : requested=${explanation.noColorRequested ? "yes" : "no"} honored=${explanation.noColorHonored ? "yes" : "no"}`,
|
|
240
|
+
` active theme : ${active.name} (mode ${active.mode})`,
|
|
241
|
+
` theme schema : ${schemaStatus}`,
|
|
242
|
+
"",
|
|
243
|
+
].join("\n"));
|
|
244
|
+
}
|
|
204
245
|
async execute() {
|
|
246
|
+
await this.writeColorThemeSection();
|
|
205
247
|
return this.executePipeline("run health checks", "doctor");
|
|
206
248
|
}
|
|
207
249
|
}
|
|
@@ -265,36 +307,105 @@ export class ThemeCommand extends OmkCommand {
|
|
|
265
307
|
],
|
|
266
308
|
});
|
|
267
309
|
nameArgs = Option.Rest({ required: 0 });
|
|
310
|
+
noColor = Option.Boolean("--no-color", false, { description: "Disable color output (NO_COLOR equivalent)" });
|
|
311
|
+
/** Detect the degradation tier, honoring the command's --no-color flag. */
|
|
312
|
+
async detectTier() {
|
|
313
|
+
const { detectColorTier } = await import("../theme/terminal-capability.js");
|
|
314
|
+
return detectColorTier(this.noColor ? ["--no-color"] : []);
|
|
315
|
+
}
|
|
268
316
|
async execute() {
|
|
269
317
|
const name = this.nameArgs.join(" ").trim();
|
|
270
318
|
const subcommand = this.nameArgs[0] ?? "";
|
|
271
319
|
const target = this.nameArgs.slice(1).join(" ").trim();
|
|
272
|
-
// omk theme list —
|
|
320
|
+
// omk theme list — active theme + omk.theme.v1 documents + builtin swatches
|
|
273
321
|
if (subcommand === "list") {
|
|
274
322
|
const { renderAllThemePreviews, getBuiltinTheme } = await import("../theme/theme-registry.js");
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
|
|
323
|
+
const { resolveTheme } = await import("../theme/theme-resolver.js");
|
|
324
|
+
const { listThemeDocuments, loadThemeDocument, validateThemeDocument } = await import("../theme/theme-doc.js");
|
|
325
|
+
const active = resolveTheme({ cwd: this.cwd, flagTheme: this.theme || undefined });
|
|
326
|
+
const tier = await this.detectTier();
|
|
327
|
+
const currentPalette = getBuiltinTheme(active.name) ?? getBuiltinTheme("omk");
|
|
328
|
+
this.context.stdout.write((currentPalette?.render("header", `Active theme: ${active.name}`) ?? `Active theme: ${active.name}`)
|
|
329
|
+
+ ` (mode ${active.mode}, tier ${tier})\n\n`);
|
|
330
|
+
const docs = listThemeDocuments(this.cwd);
|
|
331
|
+
if (docs.length > 0) {
|
|
332
|
+
this.context.stdout.write("Theme documents (omk.theme.v1):\n");
|
|
333
|
+
for (const ref of docs) {
|
|
334
|
+
const doc = loadThemeDocument(ref.name, this.cwd);
|
|
335
|
+
const valid = doc !== undefined && validateThemeDocument(doc).length === 0;
|
|
336
|
+
const marker = ref.name === active.name ? "●" : "○";
|
|
337
|
+
this.context.stdout.write(` ${marker} ${ref.name} — ${ref.path} (${valid ? "valid" : "INVALID"})\n`);
|
|
338
|
+
}
|
|
339
|
+
this.context.stdout.write("\n");
|
|
340
|
+
}
|
|
341
|
+
this.context.stdout.write("Built-in palettes:\n");
|
|
278
342
|
this.context.stdout.write(renderAllThemePreviews() + "\n");
|
|
279
343
|
return 0;
|
|
280
344
|
}
|
|
281
|
-
// omk theme
|
|
345
|
+
// omk theme set <name> — validate + persist choice to project config
|
|
346
|
+
if (subcommand === "set") {
|
|
347
|
+
if (!target) {
|
|
348
|
+
this.context.stderr.write("Usage: omk theme set <name>\n");
|
|
349
|
+
return 2;
|
|
350
|
+
}
|
|
351
|
+
const { getBuiltinTheme, listBuiltinThemes } = await import("../theme/theme-registry.js");
|
|
352
|
+
const { listThemeDocuments } = await import("../theme/theme-doc.js");
|
|
353
|
+
const docNames = listThemeDocuments(this.cwd).map((r) => r.name);
|
|
354
|
+
const known = getBuiltinTheme(target) !== undefined || docNames.includes(target);
|
|
355
|
+
if (!known) {
|
|
356
|
+
this.context.stderr.write(`Unknown theme: ${target}\n`);
|
|
357
|
+
this.context.stderr.write(`Available: ${[...new Set([...docNames, ...listBuiltinThemes()])].join(", ")}\n`);
|
|
358
|
+
return 2;
|
|
359
|
+
}
|
|
360
|
+
const { readFile, writeFile } = await import("node:fs/promises");
|
|
361
|
+
const { resolve } = await import("node:path");
|
|
362
|
+
const cfgPath = resolve(this.cwd, ".omkrc.json");
|
|
363
|
+
let existing = {};
|
|
364
|
+
try {
|
|
365
|
+
existing = JSON.parse(await readFile(cfgPath, "utf8"));
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
existing = {};
|
|
369
|
+
}
|
|
370
|
+
const next = { ...existing, theme: target };
|
|
371
|
+
await writeFile(cfgPath, JSON.stringify(next, null, 2) + "\n");
|
|
372
|
+
process.env.OMK_THEME = target;
|
|
373
|
+
this.context.stdout.write(`Theme set to: ${target} (persisted to ${cfgPath})\n`);
|
|
374
|
+
return 0;
|
|
375
|
+
}
|
|
376
|
+
// omk theme preview <name> — representative status frame at detected tier
|
|
377
|
+
// (same frame as test/theme-degradation.test.mjs) for omk.theme.v1 docs;
|
|
378
|
+
// falls back to the builtin palette swatch for registry-only themes.
|
|
282
379
|
if (subcommand === "preview") {
|
|
283
380
|
if (!target) {
|
|
284
381
|
this.context.stderr.write("Usage: omk theme preview <name>\n");
|
|
285
382
|
return 2;
|
|
286
383
|
}
|
|
384
|
+
const { loadThemeDocument, listThemeDocuments } = await import("../theme/theme-doc.js");
|
|
385
|
+
const doc = loadThemeDocument(target, this.cwd);
|
|
386
|
+
if (doc !== undefined) {
|
|
387
|
+
const { compileTheme } = await import("../theme/render-table.js");
|
|
388
|
+
const { renderStatusFrame } = await import("../theme/status-frame.js");
|
|
389
|
+
const tier = await this.detectTier();
|
|
390
|
+
const compiled = compileTheme(doc, tier);
|
|
391
|
+
this.context.stdout.write(`${doc.displayName ?? doc.name} — tier ${tier}\n\n`);
|
|
392
|
+
this.context.stdout.write(renderStatusFrame(compiled) + "\n");
|
|
393
|
+
const current = process.env.OMK_THEME ?? "omk";
|
|
394
|
+
this.context.stdout.write(`\nCurrent theme: ${current}. Use \`omk theme set ${target}\` to switch.\n`);
|
|
395
|
+
return 0;
|
|
396
|
+
}
|
|
287
397
|
const { renderThemePreview, getBuiltinTheme, listBuiltinThemes } = await import("../theme/theme-registry.js");
|
|
288
398
|
const palette = getBuiltinTheme(target);
|
|
289
399
|
if (!palette) {
|
|
290
|
-
const
|
|
400
|
+
const docNames = listThemeDocuments(this.cwd).map((r) => r.name);
|
|
401
|
+
const available = [...new Set([...docNames, ...listBuiltinThemes()])].join(", ");
|
|
291
402
|
this.context.stderr.write(`Unknown theme: ${target}\n`);
|
|
292
403
|
this.context.stderr.write(`Available: ${available}\n`);
|
|
293
404
|
return 2;
|
|
294
405
|
}
|
|
295
406
|
this.context.stdout.write(renderThemePreview(palette) + "\n");
|
|
296
407
|
const current = process.env.OMK_THEME ?? "omk";
|
|
297
|
-
this.context.stdout.write(`\nCurrent theme: ${current}. Use \`omk theme ${target}\` to switch.\n`);
|
|
408
|
+
this.context.stdout.write(`\nCurrent theme: ${current}. Use \`omk theme set ${target}\` to switch.\n`);
|
|
298
409
|
return 0;
|
|
299
410
|
}
|
|
300
411
|
// omk theme <name> — set theme
|
|
@@ -321,10 +432,11 @@ export class ThemeCommand extends OmkCommand {
|
|
|
321
432
|
* Register all v2 commands on a Clipanion CLI instance.
|
|
322
433
|
*/
|
|
323
434
|
export function createCliV2() {
|
|
435
|
+
const packageVersion = getOmkVersionSync();
|
|
324
436
|
const cli = new Cli({
|
|
325
|
-
binaryLabel: "OMK
|
|
437
|
+
binaryLabel: "OMK root orchestrator",
|
|
326
438
|
binaryName: "omk",
|
|
327
|
-
binaryVersion:
|
|
439
|
+
binaryVersion: `${packageVersion} (${OMK_RUNTIME_VERSION})`,
|
|
328
440
|
});
|
|
329
441
|
cli.register(ChatCommand);
|
|
330
442
|
cli.register(RunCommand);
|
|
@@ -47,5 +47,6 @@ export declare function withSpinner<T>(message: string, fn: () => Promise<T>): P
|
|
|
47
47
|
/**
|
|
48
48
|
* Intro/outro for OMK session.
|
|
49
49
|
*/
|
|
50
|
+
export declare function formatOmkIntroTitle(version: string): string;
|
|
50
51
|
export declare function omkIntro(version: string): void;
|
|
51
52
|
export declare function omkOutro(message: string): void;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - Progress feedback during long operations
|
|
9
9
|
*/
|
|
10
10
|
import * as clack from "@clack/prompts";
|
|
11
|
+
import { OMK_RUNTIME_VERSION } from "../../version.js";
|
|
11
12
|
/**
|
|
12
13
|
* Interactive provider selection.
|
|
13
14
|
* Returns selected provider/model string.
|
|
@@ -49,7 +50,7 @@ export async function promptThemeSelection(currentTheme) {
|
|
|
49
50
|
{ value: "omk", label: "OMK", hint: "Default colorful theme" },
|
|
50
51
|
{ value: "night-city", label: "Night City", hint: "README control image palette" },
|
|
51
52
|
{ value: "green-rain", label: "Green Rain", hint: "Phosphor signal console" },
|
|
52
|
-
{ value: "rust-forge", label: "Rust Forge", hint: "
|
|
53
|
+
{ value: "rust-forge", label: "Rust Forge", hint: "Oxidized forge control console" },
|
|
53
54
|
{ value: "neon-circuit", label: "Neon Circuit", hint: "High-energy neon terminal" },
|
|
54
55
|
{ value: "matrix", label: "Matrix", hint: "Classic green-on-black phosphor" },
|
|
55
56
|
{ value: "minimal", label: "Minimal", hint: "Clean, few colors" },
|
|
@@ -167,8 +168,11 @@ export async function withSpinner(message, fn) {
|
|
|
167
168
|
/**
|
|
168
169
|
* Intro/outro for OMK session.
|
|
169
170
|
*/
|
|
171
|
+
export function formatOmkIntroTitle(version) {
|
|
172
|
+
return `OMK root orchestrator · package v${version} · runtime ${OMK_RUNTIME_VERSION}`;
|
|
173
|
+
}
|
|
170
174
|
export function omkIntro(version) {
|
|
171
|
-
clack.intro(
|
|
175
|
+
clack.intro(formatOmkIntroTitle(version));
|
|
172
176
|
}
|
|
173
177
|
export function omkOutro(message) {
|
|
174
178
|
clack.outro(message);
|
|
@@ -300,7 +300,7 @@ export async function chatCommand(options) {
|
|
|
300
300
|
}
|
|
301
301
|
// ── plain / inline: run OMK native chat loop ──
|
|
302
302
|
const isPlain = layout === "plain";
|
|
303
|
-
const
|
|
303
|
+
const isOmkRootEntry = process.env.OMK_ENTRY_SURFACE === "omk-root-orchestrator";
|
|
304
304
|
if (!isPlain && ui !== "green-rain" && ui !== "neon-grid" && ui !== "rust-forge") {
|
|
305
305
|
const trust = `${effectiveResources.mcpScope} MCP / ${effectiveResources.skillsScope} skills`;
|
|
306
306
|
const agentDisplay = relative(root, effectiveAgentFile);
|
|
@@ -316,7 +316,7 @@ export async function chatCommand(options) {
|
|
|
316
316
|
}) + "\n");
|
|
317
317
|
}
|
|
318
318
|
// ── Deferred HUD + history: fire-and-forget, let the agent loop start immediately ──
|
|
319
|
-
if (!isPlain && !
|
|
319
|
+
if (!isPlain && !isOmkRootEntry) {
|
|
320
320
|
// Show a minimal status line while we defer the full HUD
|
|
321
321
|
const providerLabel = providerPolicy === "auto" ? "auto-detect" : providerPolicy;
|
|
322
322
|
const modeLabel = currentMode;
|
|
@@ -18,6 +18,7 @@ import { GreenRainRenderer } from "../../cli/ui/green-rain-renderer.js";
|
|
|
18
18
|
import { NeonGridRenderer } from "../../cli/ui/neon-grid-renderer.js";
|
|
19
19
|
import { RustForgeRenderer } from "../../cli/ui/rust-forge-renderer.js";
|
|
20
20
|
import { sanitizeUserVisibleOutput } from "../../util/user-visible-output.js";
|
|
21
|
+
import { setBrandPaletteTheme } from "../../brand/palette.js";
|
|
21
22
|
export function shouldUseDirectKimiFallback() {
|
|
22
23
|
return false;
|
|
23
24
|
}
|
|
@@ -237,6 +238,7 @@ export async function runChatRuntime(options, input) {
|
|
|
237
238
|
process.stdout.write(sanitizeUserVisibleOutput(text));
|
|
238
239
|
},
|
|
239
240
|
});
|
|
241
|
+
setBrandPaletteTheme(ui === "rust-forge" ? "rust-forge" : process.env.OMK_THEME);
|
|
240
242
|
const renderer = ui === "neon-grid"
|
|
241
243
|
? new NeonGridRenderer()
|
|
242
244
|
: ui === "green-rain"
|
|
@@ -8,6 +8,9 @@ import { readFile, readdir } from "fs/promises";
|
|
|
8
8
|
import YAML from "yaml";
|
|
9
9
|
import { t } from "../../util/i18n.js";
|
|
10
10
|
import { getActiveRuntimePreset } from "../../util/resource-profile.js";
|
|
11
|
+
import { setBrandPaletteTheme } from "../../brand/palette.js";
|
|
12
|
+
import { getOmkVersionSync } from "../../util/version.js";
|
|
13
|
+
import { OMK_RUNTIME_VERSION } from "../../version.js";
|
|
11
14
|
export function mergeTodos(existing, incoming) {
|
|
12
15
|
const map = new Map();
|
|
13
16
|
for (const t of existing) {
|
|
@@ -79,6 +82,7 @@ export function resolveChatWorkerCount(requested, fallback) {
|
|
|
79
82
|
return trimmed;
|
|
80
83
|
}
|
|
81
84
|
export function renderChatIntro(brand, meta) {
|
|
85
|
+
setBrandPaletteTheme(brand === "rust-forge" ? "rust-forge" : process.env.OMK_THEME);
|
|
82
86
|
const titleKey = {
|
|
83
87
|
omk: "chat.intro.omk",
|
|
84
88
|
"green-rain": "chat.intro.greenRain",
|
|
@@ -102,20 +106,24 @@ export function renderChatIntro(brand, meta) {
|
|
|
102
106
|
lines.push("");
|
|
103
107
|
}
|
|
104
108
|
else if (brand === "rust-forge") {
|
|
105
|
-
lines.push(style.rustBold("▣ OMK//RUST-FORGE"));
|
|
106
|
-
lines.push(style.gray("
|
|
107
|
-
lines.push(style.gray("
|
|
109
|
+
lines.push(style.rustBold("▣ OMK//RUST-FORGE · ROOT ORCHESTRATOR"));
|
|
110
|
+
lines.push(style.gray(" OXIDIZED FORGE ONLINE"));
|
|
111
|
+
lines.push(style.gray(" OMK independent control: adapters are lanes, evidence is authority."));
|
|
112
|
+
lines.push(style.gray(" Heat: hot · Anvil: locked · Quench: ready · Loop: controlled."));
|
|
108
113
|
for (const artLine of OMK_SIMPLE_ASCII_ART.split("\n")) {
|
|
109
114
|
lines.push(style.rust(artLine));
|
|
110
115
|
}
|
|
111
116
|
lines.push("");
|
|
112
117
|
}
|
|
113
118
|
else if (brand !== "plain") {
|
|
114
|
-
lines.push(style.phosphorBold("◇ OMK//CONTROL"));
|
|
119
|
+
lines.push(style.phosphorBold("◇ OMK//CONTROL · ROOT ORCHESTRATOR"));
|
|
115
120
|
lines.push(style.gray(" OMK ONLINE"));
|
|
116
121
|
lines.push(style.gray(" Route: online · Verify: armed · Loop: controlled."));
|
|
117
122
|
lines.push("");
|
|
118
123
|
}
|
|
124
|
+
if (brand !== "plain") {
|
|
125
|
+
lines.push(style.gray(` package v${getOmkVersionSync()} · runtime ${OMK_RUNTIME_VERSION}`));
|
|
126
|
+
}
|
|
119
127
|
lines.push(style.phosphorBold(`▸ ${title}`));
|
|
120
128
|
if (brand !== "plain") {
|
|
121
129
|
lines.push(` ${style.gray(t("chat.intro.agent") + ":")} ${style.cream(meta.agent)}`);
|