magi-ai 0.1.0
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/LICENSE +21 -0
- package/README.ja.md +377 -0
- package/README.md +377 -0
- package/dist/bin/magi-benchmark.d.ts +14 -0
- package/dist/bin/magi-benchmark.js +93 -0
- package/dist/bin/magi-mcp.d.ts +8 -0
- package/dist/bin/magi-mcp.js +28 -0
- package/dist/bin/magi.d.ts +2 -0
- package/dist/bin/magi.js +634 -0
- package/dist/src/adapters/base.d.ts +34 -0
- package/dist/src/adapters/base.js +149 -0
- package/dist/src/adapters/claude.d.ts +29 -0
- package/dist/src/adapters/claude.js +65 -0
- package/dist/src/adapters/codex.d.ts +21 -0
- package/dist/src/adapters/codex.js +41 -0
- package/dist/src/adapters/gemini.d.ts +18 -0
- package/dist/src/adapters/gemini.js +31 -0
- package/dist/src/adapters/registry.d.ts +19 -0
- package/dist/src/adapters/registry.js +59 -0
- package/dist/src/audit/hash-chain.d.ts +21 -0
- package/dist/src/audit/hash-chain.js +70 -0
- package/dist/src/audit/types.d.ts +25 -0
- package/dist/src/audit/types.js +1 -0
- package/dist/src/audit/writer.d.ts +18 -0
- package/dist/src/audit/writer.js +100 -0
- package/dist/src/benchmark/golden-tasks.d.ts +9 -0
- package/dist/src/benchmark/golden-tasks.js +476 -0
- package/dist/src/benchmark/reporter.d.ts +5 -0
- package/dist/src/benchmark/reporter.js +107 -0
- package/dist/src/benchmark/runner.d.ts +30 -0
- package/dist/src/benchmark/runner.js +224 -0
- package/dist/src/benchmark/scorer.d.ts +12 -0
- package/dist/src/benchmark/scorer.js +124 -0
- package/dist/src/benchmark/types.d.ts +54 -0
- package/dist/src/benchmark/types.js +1 -0
- package/dist/src/cache/deliberation-cache.d.ts +49 -0
- package/dist/src/cache/deliberation-cache.js +127 -0
- package/dist/src/cli/commands/config-cmd.d.ts +11 -0
- package/dist/src/cli/commands/config-cmd.js +190 -0
- package/dist/src/cli/commands/demo.d.ts +12 -0
- package/dist/src/cli/commands/demo.js +66 -0
- package/dist/src/cli/commands/setup.d.ts +7 -0
- package/dist/src/cli/commands/setup.js +182 -0
- package/dist/src/cli/i18n.d.ts +89 -0
- package/dist/src/cli/i18n.js +176 -0
- package/dist/src/cli/interactive-select.d.ts +27 -0
- package/dist/src/cli/interactive-select.js +130 -0
- package/dist/src/cli/tui-setup.d.ts +24 -0
- package/dist/src/cli/tui-setup.js +42 -0
- package/dist/src/config/cli-detector.d.ts +37 -0
- package/dist/src/config/cli-detector.js +99 -0
- package/dist/src/config/user-config.d.ts +81 -0
- package/dist/src/config/user-config.js +134 -0
- package/dist/src/context/auto-collector.d.ts +43 -0
- package/dist/src/context/auto-collector.js +337 -0
- package/dist/src/context/manager.d.ts +35 -0
- package/dist/src/context/manager.js +162 -0
- package/dist/src/context/serializer.d.ts +20 -0
- package/dist/src/context/serializer.js +52 -0
- package/dist/src/demo/recorded-deliberation.d.ts +13 -0
- package/dist/src/demo/recorded-deliberation.js +277 -0
- package/dist/src/engine/angel-detector.d.ts +83 -0
- package/dist/src/engine/angel-detector.js +334 -0
- package/dist/src/engine/at-field.d.ts +40 -0
- package/dist/src/engine/at-field.js +195 -0
- package/dist/src/engine/berserk-orchestrator.d.ts +66 -0
- package/dist/src/engine/berserk-orchestrator.js +378 -0
- package/dist/src/engine/change-metrics.d.ts +56 -0
- package/dist/src/engine/change-metrics.js +214 -0
- package/dist/src/engine/consensus.d.ts +20 -0
- package/dist/src/engine/consensus.js +146 -0
- package/dist/src/engine/dead-sea-scrolls.d.ts +132 -0
- package/dist/src/engine/dead-sea-scrolls.js +610 -0
- package/dist/src/engine/drift-detector.d.ts +39 -0
- package/dist/src/engine/drift-detector.js +225 -0
- package/dist/src/engine/dummy-plug.d.ts +44 -0
- package/dist/src/engine/dummy-plug.js +190 -0
- package/dist/src/engine/engram-manager.d.ts +55 -0
- package/dist/src/engine/engram-manager.js +306 -0
- package/dist/src/engine/events.d.ts +130 -0
- package/dist/src/engine/events.js +44 -0
- package/dist/src/engine/gospel.d.ts +30 -0
- package/dist/src/engine/gospel.js +129 -0
- package/dist/src/engine/hallucination-detector.d.ts +33 -0
- package/dist/src/engine/hallucination-detector.js +215 -0
- package/dist/src/engine/human-resolver.d.ts +19 -0
- package/dist/src/engine/human-resolver.js +89 -0
- package/dist/src/engine/instrumentality.d.ts +64 -0
- package/dist/src/engine/instrumentality.js +297 -0
- package/dist/src/engine/iruel-battle.d.ts +79 -0
- package/dist/src/engine/iruel-battle.js +319 -0
- package/dist/src/engine/kernel/deliberation-kernel.d.ts +12 -0
- package/dist/src/engine/kernel/deliberation-kernel.js +303 -0
- package/dist/src/engine/kernel/index.d.ts +8 -0
- package/dist/src/engine/kernel/index.js +7 -0
- package/dist/src/engine/kernel/phase-runner.d.ts +10 -0
- package/dist/src/engine/kernel/phase-runner.js +155 -0
- package/dist/src/engine/kernel/post-processor.d.ts +17 -0
- package/dist/src/engine/kernel/post-processor.js +131 -0
- package/dist/src/engine/kernel/types.d.ts +107 -0
- package/dist/src/engine/kernel/types.js +1 -0
- package/dist/src/engine/kernel/unit-executor.d.ts +6 -0
- package/dist/src/engine/kernel/unit-executor.js +132 -0
- package/dist/src/engine/lcl-manager.d.ts +44 -0
- package/dist/src/engine/lcl-manager.js +143 -0
- package/dist/src/engine/middleware/cache.d.ts +7 -0
- package/dist/src/engine/middleware/cache.js +29 -0
- package/dist/src/engine/middleware/chain.d.ts +18 -0
- package/dist/src/engine/middleware/chain.js +45 -0
- package/dist/src/engine/middleware/firewall.d.ts +8 -0
- package/dist/src/engine/middleware/firewall.js +24 -0
- package/dist/src/engine/middleware/index.d.ts +4 -0
- package/dist/src/engine/middleware/index.js +3 -0
- package/dist/src/engine/middleware/types.d.ts +43 -0
- package/dist/src/engine/middleware/types.js +1 -0
- package/dist/src/engine/nebuchadnezzar-key.d.ts +61 -0
- package/dist/src/engine/nebuchadnezzar-key.js +203 -0
- package/dist/src/engine/neon-genesis.d.ts +52 -0
- package/dist/src/engine/neon-genesis.js +203 -0
- package/dist/src/engine/objective-judge.d.ts +53 -0
- package/dist/src/engine/objective-judge.js +214 -0
- package/dist/src/engine/offline-mode.d.ts +18 -0
- package/dist/src/engine/offline-mode.js +46 -0
- package/dist/src/engine/orchestrator.d.ts +79 -0
- package/dist/src/engine/orchestrator.js +58 -0
- package/dist/src/engine/secret-cipher.d.ts +26 -0
- package/dist/src/engine/secret-cipher.js +114 -0
- package/dist/src/engine/seele-council.d.ts +90 -0
- package/dist/src/engine/seele-council.js +482 -0
- package/dist/src/engine/self-destruct.d.ts +61 -0
- package/dist/src/engine/self-destruct.js +231 -0
- package/dist/src/engine/self-evolution.d.ts +64 -0
- package/dist/src/engine/self-evolution.js +368 -0
- package/dist/src/engine/sync-rate.d.ts +45 -0
- package/dist/src/engine/sync-rate.js +151 -0
- package/dist/src/engine/type666-firewall.d.ts +76 -0
- package/dist/src/engine/type666-firewall.js +343 -0
- package/dist/src/engine/umbilical-cable.d.ts +41 -0
- package/dist/src/engine/umbilical-cable.js +192 -0
- package/dist/src/index.d.ts +106 -0
- package/dist/src/index.js +426 -0
- package/dist/src/mcp/server.d.ts +38 -0
- package/dist/src/mcp/server.js +196 -0
- package/dist/src/metrics/token-tracker.d.ts +38 -0
- package/dist/src/metrics/token-tracker.js +112 -0
- package/dist/src/parsers/json-extractor.d.ts +9 -0
- package/dist/src/parsers/json-extractor.js +239 -0
- package/dist/src/parsers/opinion-schema.d.ts +81 -0
- package/dist/src/parsers/opinion-schema.js +147 -0
- package/dist/src/parsers/unstructured-parser.d.ts +20 -0
- package/dist/src/parsers/unstructured-parser.js +122 -0
- package/dist/src/pipelines/architecture.d.ts +10 -0
- package/dist/src/pipelines/architecture.js +9 -0
- package/dist/src/pipelines/bug-analysis.d.ts +9 -0
- package/dist/src/pipelines/bug-analysis.js +8 -0
- package/dist/src/pipelines/code-review.d.ts +10 -0
- package/dist/src/pipelines/code-review.js +30 -0
- package/dist/src/pipelines/custom.d.ts +14 -0
- package/dist/src/pipelines/custom.js +29 -0
- package/dist/src/pipelines/registry.d.ts +9 -0
- package/dist/src/pipelines/registry.js +20 -0
- package/dist/src/prompts/personas.d.ts +6 -0
- package/dist/src/prompts/personas.js +44 -0
- package/dist/src/prompts/schemas.d.ts +4 -0
- package/dist/src/prompts/schemas.js +24 -0
- package/dist/src/prompts/templates.d.ts +6 -0
- package/dist/src/prompts/templates.js +91 -0
- package/dist/src/repl/accessibility.d.ts +23 -0
- package/dist/src/repl/accessibility.js +46 -0
- package/dist/src/repl/banner.d.ts +4 -0
- package/dist/src/repl/banner.js +28 -0
- package/dist/src/repl/boot-animation.d.ts +13 -0
- package/dist/src/repl/boot-animation.js +143 -0
- package/dist/src/repl/completer.d.ts +21 -0
- package/dist/src/repl/completer.js +168 -0
- package/dist/src/repl/context.d.ts +24 -0
- package/dist/src/repl/context.js +42 -0
- package/dist/src/repl/display-utils.d.ts +13 -0
- package/dist/src/repl/display-utils.js +65 -0
- package/dist/src/repl/event-listener.d.ts +18 -0
- package/dist/src/repl/event-listener.js +112 -0
- package/dist/src/repl/export-formatter.d.ts +8 -0
- package/dist/src/repl/export-formatter.js +73 -0
- package/dist/src/repl/ghost-text.d.ts +31 -0
- package/dist/src/repl/ghost-text.js +119 -0
- package/dist/src/repl/handoff-animation.d.ts +15 -0
- package/dist/src/repl/handoff-animation.js +65 -0
- package/dist/src/repl/history.d.ts +16 -0
- package/dist/src/repl/history.js +130 -0
- package/dist/src/repl/job-registry.d.ts +26 -0
- package/dist/src/repl/job-registry.js +80 -0
- package/dist/src/repl/magi-repl.d.ts +72 -0
- package/dist/src/repl/magi-repl.js +1008 -0
- package/dist/src/repl/multiline-input.d.ts +45 -0
- package/dist/src/repl/multiline-input.js +78 -0
- package/dist/src/repl/prompt-builder.d.ts +19 -0
- package/dist/src/repl/prompt-builder.js +36 -0
- package/dist/src/repl/repl-state.d.ts +5 -0
- package/dist/src/repl/repl-state.js +19 -0
- package/dist/src/repl/result-display.d.ts +8 -0
- package/dist/src/repl/result-display.js +195 -0
- package/dist/src/repl/session-stats.d.ts +26 -0
- package/dist/src/repl/session-stats.js +119 -0
- package/dist/src/repl/slash-commands.d.ts +60 -0
- package/dist/src/repl/slash-commands.js +725 -0
- package/dist/src/repl/terminal-sanitize.d.ts +14 -0
- package/dist/src/repl/terminal-sanitize.js +19 -0
- package/dist/src/reporters/console.d.ts +7 -0
- package/dist/src/reporters/console.js +78 -0
- package/dist/src/reporters/json.d.ts +2 -0
- package/dist/src/reporters/json.js +3 -0
- package/dist/src/reporters/markdown.d.ts +2 -0
- package/dist/src/reporters/markdown.js +65 -0
- package/dist/src/reporters/streaming.d.ts +20 -0
- package/dist/src/reporters/streaming.js +178 -0
- package/dist/src/tui/activity-log.d.ts +23 -0
- package/dist/src/tui/activity-log.js +67 -0
- package/dist/src/tui/animations.d.ts +39 -0
- package/dist/src/tui/animations.js +167 -0
- package/dist/src/tui/ansi.d.ts +28 -0
- package/dist/src/tui/ansi.js +51 -0
- package/dist/src/tui/boot-sequence.d.ts +11 -0
- package/dist/src/tui/boot-sequence.js +98 -0
- package/dist/src/tui/colors.d.ts +101 -0
- package/dist/src/tui/colors.js +71 -0
- package/dist/src/tui/header.d.ts +24 -0
- package/dist/src/tui/header.js +122 -0
- package/dist/src/tui/index.d.ts +3 -0
- package/dist/src/tui/index.js +3 -0
- package/dist/src/tui/keypress.d.ts +25 -0
- package/dist/src/tui/keypress.js +95 -0
- package/dist/src/tui/layout.d.ts +74 -0
- package/dist/src/tui/layout.js +171 -0
- package/dist/src/tui/magi-tui.d.ts +101 -0
- package/dist/src/tui/magi-tui.js +754 -0
- package/dist/src/tui/panel.d.ts +45 -0
- package/dist/src/tui/panel.js +292 -0
- package/dist/src/tui/screen-buffer.d.ts +54 -0
- package/dist/src/tui/screen-buffer.js +262 -0
- package/dist/src/tui/status-bar.d.ts +25 -0
- package/dist/src/tui/status-bar.js +124 -0
- package/dist/src/tui/terminal-detect.d.ts +26 -0
- package/dist/src/tui/terminal-detect.js +44 -0
- package/dist/src/tui/tui-helpers.d.ts +12 -0
- package/dist/src/tui/tui-helpers.js +37 -0
- package/dist/src/types/adapter.d.ts +75 -0
- package/dist/src/types/adapter.js +36 -0
- package/dist/src/types/config.d.ts +108 -0
- package/dist/src/types/config.js +85 -0
- package/dist/src/types/consensus.d.ts +55 -0
- package/dist/src/types/consensus.js +17 -0
- package/dist/src/types/core.d.ts +178 -0
- package/dist/src/types/core.js +85 -0
- package/dist/src/types/magi-api.d.ts +62 -0
- package/dist/src/types/magi-api.js +7 -0
- package/dist/src/types/phase-h.d.ts +142 -0
- package/dist/src/types/phase-h.js +7 -0
- package/dist/src/types/phase-i.d.ts +186 -0
- package/dist/src/types/phase-i.js +6 -0
- package/dist/src/types/phase-k.d.ts +259 -0
- package/dist/src/types/phase-k.js +6 -0
- package/dist/src/types/phase-l.d.ts +199 -0
- package/dist/src/types/phase-l.js +6 -0
- package/dist/src/types/pipeline.d.ts +37 -0
- package/dist/src/types/pipeline.js +2 -0
- package/dist/src/utils/abstain-factory.d.ts +2 -0
- package/dist/src/utils/abstain-factory.js +18 -0
- package/dist/src/utils/errors.d.ts +34 -0
- package/dist/src/utils/errors.js +59 -0
- package/dist/src/utils/file-validator.d.ts +50 -0
- package/dist/src/utils/file-validator.js +124 -0
- package/dist/src/utils/fire-and-forget.d.ts +5 -0
- package/dist/src/utils/fire-and-forget.js +10 -0
- package/dist/src/utils/flag-validator.d.ts +21 -0
- package/dist/src/utils/flag-validator.js +79 -0
- package/dist/src/utils/freeze.d.ts +8 -0
- package/dist/src/utils/freeze.js +16 -0
- package/dist/src/utils/language-detector.d.ts +16 -0
- package/dist/src/utils/language-detector.js +159 -0
- package/dist/src/utils/latency-tracker.d.ts +45 -0
- package/dist/src/utils/latency-tracker.js +100 -0
- package/dist/src/utils/logger.d.ts +33 -0
- package/dist/src/utils/logger.js +112 -0
- package/dist/src/utils/process.d.ts +40 -0
- package/dist/src/utils/process.js +253 -0
- package/dist/src/utils/retry.d.ts +12 -0
- package/dist/src/utils/retry.js +30 -0
- package/dist/src/utils/safe-fs.d.ts +38 -0
- package/dist/src/utils/safe-fs.js +56 -0
- package/dist/src/utils/safe-json-parse.d.ts +15 -0
- package/dist/src/utils/safe-json-parse.js +49 -0
- package/dist/src/utils/sanitize.d.ts +14 -0
- package/dist/src/utils/sanitize.js +186 -0
- package/dist/src/utils/semaphore.d.ts +22 -0
- package/dist/src/utils/semaphore.js +57 -0
- package/dist/src/utils/shutdown.d.ts +6 -0
- package/dist/src/utils/shutdown.js +51 -0
- package/dist/src/utils/tty.d.ts +5 -0
- package/dist/src/utils/tty.js +7 -0
- package/package.json +82 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdin helpers for TUI keyboard handling.
|
|
3
|
+
*/
|
|
4
|
+
export type TuiKey = '1' | '2' | '3' | 'q' | 'escape' | 'other';
|
|
5
|
+
/**
|
|
6
|
+
* Suppress stdin echo by setting raw mode and consuming all input.
|
|
7
|
+
* Returns a cleanup function to restore stdin to its original state.
|
|
8
|
+
* Prevents escape sequences (^[[B, ^[[A, etc.) from leaking to stdout.
|
|
9
|
+
*/
|
|
10
|
+
export declare function suppressStdin(onKey?: (key: TuiKey) => void): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Wait for a single keypress from stdin.
|
|
13
|
+
* If stdin is not a TTY, falls back to a 3-second timeout.
|
|
14
|
+
*/
|
|
15
|
+
export declare function waitForKeypress(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Parse a raw stdin Buffer into TuiKey events.
|
|
18
|
+
*
|
|
19
|
+
* Properly skips CSI (`\x1b[...`) and SS3 (`\x1bO.`) escape sequences
|
|
20
|
+
* so that arrow keys, function keys, and modifier combos are never
|
|
21
|
+
* misinterpreted as literal '1'/'2'/'3' or 'escape'.
|
|
22
|
+
*
|
|
23
|
+
* A bare `\x1b` (with no following `[` or `O`) is the real Escape key.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeKeys(chunk: Buffer): TuiKey[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdin helpers for TUI keyboard handling.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Suppress stdin echo by setting raw mode and consuming all input.
|
|
6
|
+
* Returns a cleanup function to restore stdin to its original state.
|
|
7
|
+
* Prevents escape sequences (^[[B, ^[[A, etc.) from leaking to stdout.
|
|
8
|
+
*/
|
|
9
|
+
export function suppressStdin(onKey) {
|
|
10
|
+
if (!process.stdin.isTTY)
|
|
11
|
+
return () => { };
|
|
12
|
+
const wasRaw = process.stdin.isRaw;
|
|
13
|
+
const wasFlowing = process.stdin.readableFlowing;
|
|
14
|
+
process.stdin.setRawMode(true);
|
|
15
|
+
process.stdin.resume();
|
|
16
|
+
// Consume all input silently
|
|
17
|
+
const drain = (chunk) => {
|
|
18
|
+
if (!onKey)
|
|
19
|
+
return;
|
|
20
|
+
for (const key of normalizeKeys(chunk)) {
|
|
21
|
+
onKey(key);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
process.stdin.on('data', drain);
|
|
25
|
+
return () => {
|
|
26
|
+
process.stdin.removeListener('data', drain);
|
|
27
|
+
process.stdin.setRawMode(wasRaw ?? false);
|
|
28
|
+
if (!wasFlowing)
|
|
29
|
+
process.stdin.pause();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Wait for a single keypress from stdin.
|
|
34
|
+
* If stdin is not a TTY, falls back to a 3-second timeout.
|
|
35
|
+
*/
|
|
36
|
+
export function waitForKeypress() {
|
|
37
|
+
if (!process.stdin.isTTY) {
|
|
38
|
+
return new Promise(resolve => setTimeout(resolve, 3000));
|
|
39
|
+
}
|
|
40
|
+
return new Promise(resolve => {
|
|
41
|
+
// stdin is already in raw mode from suppressStdin(), just listen for data
|
|
42
|
+
const handler = () => {
|
|
43
|
+
process.stdin.removeListener('data', handler);
|
|
44
|
+
resolve();
|
|
45
|
+
};
|
|
46
|
+
process.stdin.on('data', handler);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse a raw stdin Buffer into TuiKey events.
|
|
51
|
+
*
|
|
52
|
+
* Properly skips CSI (`\x1b[...`) and SS3 (`\x1bO.`) escape sequences
|
|
53
|
+
* so that arrow keys, function keys, and modifier combos are never
|
|
54
|
+
* misinterpreted as literal '1'/'2'/'3' or 'escape'.
|
|
55
|
+
*
|
|
56
|
+
* A bare `\x1b` (with no following `[` or `O`) is the real Escape key.
|
|
57
|
+
*/
|
|
58
|
+
export function normalizeKeys(chunk) {
|
|
59
|
+
const text = chunk.toString('utf8');
|
|
60
|
+
const keys = [];
|
|
61
|
+
let i = 0;
|
|
62
|
+
while (i < text.length) {
|
|
63
|
+
const ch = text[i];
|
|
64
|
+
if (ch === '\x1b') {
|
|
65
|
+
const next = text[i + 1];
|
|
66
|
+
if (next === '[') {
|
|
67
|
+
// CSI sequence: \x1b[ ... <final byte in @-~ range>
|
|
68
|
+
i += 2; // skip \x1b[
|
|
69
|
+
while (i < text.length && !(text[i] >= '@' && text[i] <= '~')) {
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
if (i < text.length)
|
|
73
|
+
i++; // skip final byte
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (next === 'O') {
|
|
77
|
+
// SS3 sequence: \x1bO + 1 char
|
|
78
|
+
i += 3;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Bare ESC — real escape key press
|
|
82
|
+
keys.push('escape');
|
|
83
|
+
i++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (ch === '1' || ch === '2' || ch === '3' || ch === 'q') {
|
|
87
|
+
keys.push(ch);
|
|
88
|
+
}
|
|
89
|
+
else if (ch >= ' ') {
|
|
90
|
+
keys.push('other');
|
|
91
|
+
}
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
return keys;
|
|
95
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inverted Y-shape layout geometry for the MAGI TUI.
|
|
3
|
+
*
|
|
4
|
+
* Layout structure:
|
|
5
|
+
* [Header] — top 5 rows
|
|
6
|
+
* [Main area] — BALTHASAR(top), MAGI node(center), CASPER(left), MELCHIOR(right)
|
|
7
|
+
* [Activity log] — 3 rows above status bar
|
|
8
|
+
* [Status bar] — bottom 2 rows
|
|
9
|
+
*/
|
|
10
|
+
export declare const HEADER_HEIGHT = 5;
|
|
11
|
+
export declare const STATUS_BAR_HEIGHT = 2;
|
|
12
|
+
export declare const ACTIVITY_LOG_LINES = 3;
|
|
13
|
+
export declare const MAGI_NODE_WIDTH = 11;
|
|
14
|
+
export declare const MAGI_NODE_HEIGHT = 3;
|
|
15
|
+
export declare const VERDICT_STAMP_WIDTH = 14;
|
|
16
|
+
export declare const VERDICT_STAMP_HEIGHT = 3;
|
|
17
|
+
export declare const MIN_PANEL_WIDTH = 20;
|
|
18
|
+
export declare const MIN_PANEL_HEIGHT = 5;
|
|
19
|
+
export type TuiProfile = 'compact' | 'standard' | 'cinematic';
|
|
20
|
+
export interface Rect {
|
|
21
|
+
readonly row: number;
|
|
22
|
+
readonly col: number;
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
}
|
|
26
|
+
export interface Connector {
|
|
27
|
+
readonly row: number;
|
|
28
|
+
readonly col: number;
|
|
29
|
+
readonly char: string;
|
|
30
|
+
}
|
|
31
|
+
export interface MagiLayout {
|
|
32
|
+
readonly profile: TuiProfile;
|
|
33
|
+
readonly header: Rect;
|
|
34
|
+
readonly verdictStamp: Rect;
|
|
35
|
+
readonly balthasarPanel: Rect;
|
|
36
|
+
readonly magiNode: Rect;
|
|
37
|
+
readonly casperPanel: Rect;
|
|
38
|
+
readonly melchiorPanel: Rect;
|
|
39
|
+
readonly connectors: Connector[];
|
|
40
|
+
readonly activityLog: Rect;
|
|
41
|
+
readonly statusBar: Rect;
|
|
42
|
+
readonly outerFrame: Rect;
|
|
43
|
+
}
|
|
44
|
+
export declare const BOX: {
|
|
45
|
+
readonly h: "─";
|
|
46
|
+
readonly v: "│";
|
|
47
|
+
readonly tl: "┌";
|
|
48
|
+
readonly tr: "┐";
|
|
49
|
+
readonly bl: "└";
|
|
50
|
+
readonly br: "┘";
|
|
51
|
+
readonly lT: "├";
|
|
52
|
+
readonly rT: "┤";
|
|
53
|
+
readonly tT: "┬";
|
|
54
|
+
readonly bT: "┴";
|
|
55
|
+
readonly x: "┼";
|
|
56
|
+
};
|
|
57
|
+
export declare const BOX_DOUBLE: {
|
|
58
|
+
readonly h: "═";
|
|
59
|
+
readonly v: "║";
|
|
60
|
+
readonly tl: "╔";
|
|
61
|
+
readonly tr: "╗";
|
|
62
|
+
readonly bl: "╚";
|
|
63
|
+
readonly br: "╝";
|
|
64
|
+
};
|
|
65
|
+
export declare const BOX_HEAVY: {
|
|
66
|
+
readonly h: "━";
|
|
67
|
+
readonly v: "┃";
|
|
68
|
+
readonly tl: "┏";
|
|
69
|
+
readonly tr: "┓";
|
|
70
|
+
readonly bl: "┗";
|
|
71
|
+
readonly br: "┛";
|
|
72
|
+
};
|
|
73
|
+
export declare function getTuiProfile(cols: number, rows: number): TuiProfile;
|
|
74
|
+
export declare function calculateLayout(cols: number, rows: number): MagiLayout;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inverted Y-shape layout geometry for the MAGI TUI.
|
|
3
|
+
*
|
|
4
|
+
* Layout structure:
|
|
5
|
+
* [Header] — top 5 rows
|
|
6
|
+
* [Main area] — BALTHASAR(top), MAGI node(center), CASPER(left), MELCHIOR(right)
|
|
7
|
+
* [Activity log] — 3 rows above status bar
|
|
8
|
+
* [Status bar] — bottom 2 rows
|
|
9
|
+
*/
|
|
10
|
+
// ── Constants ───────────────────────────────────────────────
|
|
11
|
+
export const HEADER_HEIGHT = 5;
|
|
12
|
+
export const STATUS_BAR_HEIGHT = 2;
|
|
13
|
+
export const ACTIVITY_LOG_LINES = 3;
|
|
14
|
+
export const MAGI_NODE_WIDTH = 11; // "┌─ MAGI ─┐"
|
|
15
|
+
export const MAGI_NODE_HEIGHT = 3;
|
|
16
|
+
export const VERDICT_STAMP_WIDTH = 14;
|
|
17
|
+
export const VERDICT_STAMP_HEIGHT = 3;
|
|
18
|
+
export const MIN_PANEL_WIDTH = 20;
|
|
19
|
+
export const MIN_PANEL_HEIGHT = 5;
|
|
20
|
+
// ── Box-drawing characters ──────────────────────────────────
|
|
21
|
+
export const BOX = {
|
|
22
|
+
h: '─', v: '│',
|
|
23
|
+
tl: '┌', tr: '┐', bl: '└', br: '┘',
|
|
24
|
+
lT: '├', rT: '┤', tT: '┬', bT: '┴', x: '┼',
|
|
25
|
+
};
|
|
26
|
+
export const BOX_DOUBLE = {
|
|
27
|
+
h: '═', v: '║',
|
|
28
|
+
tl: '╔', tr: '╗', bl: '╚', br: '╝',
|
|
29
|
+
};
|
|
30
|
+
export const BOX_HEAVY = {
|
|
31
|
+
h: '━', v: '┃',
|
|
32
|
+
tl: '┏', tr: '┓', bl: '┗', br: '┛',
|
|
33
|
+
};
|
|
34
|
+
// ── Layout calculation ──────────────────────────────────────
|
|
35
|
+
export function getTuiProfile(cols, rows) {
|
|
36
|
+
if (cols >= 140 && rows >= 40)
|
|
37
|
+
return 'cinematic';
|
|
38
|
+
if (cols >= 100 && rows >= 30)
|
|
39
|
+
return 'standard';
|
|
40
|
+
return 'compact';
|
|
41
|
+
}
|
|
42
|
+
export function calculateLayout(cols, rows) {
|
|
43
|
+
const profile = getTuiProfile(cols, rows);
|
|
44
|
+
const outerFrame = { row: 0, col: 0, width: cols, height: rows };
|
|
45
|
+
// Header: top rows
|
|
46
|
+
const header = { row: 0, col: 0, width: cols, height: HEADER_HEIGHT };
|
|
47
|
+
const verdictStamp = {
|
|
48
|
+
row: 1,
|
|
49
|
+
col: Math.max(2, cols - VERDICT_STAMP_WIDTH - 2),
|
|
50
|
+
width: Math.min(VERDICT_STAMP_WIDTH, Math.max(10, cols - 4)),
|
|
51
|
+
height: VERDICT_STAMP_HEIGHT,
|
|
52
|
+
};
|
|
53
|
+
// Status bar: bottom rows
|
|
54
|
+
const statusBar = {
|
|
55
|
+
row: rows - STATUS_BAR_HEIGHT,
|
|
56
|
+
col: 0,
|
|
57
|
+
width: cols,
|
|
58
|
+
height: STATUS_BAR_HEIGHT,
|
|
59
|
+
};
|
|
60
|
+
// Activity log: above status bar
|
|
61
|
+
const activityLog = {
|
|
62
|
+
row: rows - STATUS_BAR_HEIGHT - ACTIVITY_LOG_LINES,
|
|
63
|
+
col: 0,
|
|
64
|
+
width: cols,
|
|
65
|
+
height: ACTIVITY_LOG_LINES,
|
|
66
|
+
};
|
|
67
|
+
// Main area: between header and activity log.
|
|
68
|
+
// When terminal is too small, mainHeight may be 0 — panels will overlap
|
|
69
|
+
// but ScreenBuffer clips out-of-bounds writes so no crash occurs.
|
|
70
|
+
// A proper fix would enforce MIN_ROWS at the TUI entry point.
|
|
71
|
+
const mainTop = HEADER_HEIGHT;
|
|
72
|
+
const mainHeight = Math.max(0, activityLog.row - mainTop);
|
|
73
|
+
const mainCenter = Math.floor(cols / 2);
|
|
74
|
+
// --- BALTHASAR panel (top center) ---
|
|
75
|
+
const baltWidthFactor = profile === 'cinematic' ? 0.5 : profile === 'standard' ? 0.47 : 0.45;
|
|
76
|
+
const baltHeightFactor = profile === 'cinematic' ? 0.42 : profile === 'standard' ? 0.4 : 0.38;
|
|
77
|
+
const baltWidth = Math.min(Math.floor(cols * baltWidthFactor), cols - 4);
|
|
78
|
+
const baltHeight = Math.max(MIN_PANEL_HEIGHT, Math.floor(mainHeight * baltHeightFactor));
|
|
79
|
+
const baltCol = Math.floor((cols - baltWidth) / 2);
|
|
80
|
+
const balthasarPanel = {
|
|
81
|
+
row: mainTop,
|
|
82
|
+
col: baltCol,
|
|
83
|
+
width: baltWidth,
|
|
84
|
+
height: baltHeight,
|
|
85
|
+
};
|
|
86
|
+
// --- MAGI node (center junction) ---
|
|
87
|
+
const magiRow = mainTop + baltHeight;
|
|
88
|
+
const magiCol = mainCenter - Math.floor(MAGI_NODE_WIDTH / 2);
|
|
89
|
+
const magiNode = {
|
|
90
|
+
row: magiRow,
|
|
91
|
+
col: magiCol,
|
|
92
|
+
width: MAGI_NODE_WIDTH,
|
|
93
|
+
height: MAGI_NODE_HEIGHT,
|
|
94
|
+
};
|
|
95
|
+
// --- Bottom panels: CASPER (left) and MELCHIOR (right) ---
|
|
96
|
+
const bottomTop = magiRow + MAGI_NODE_HEIGHT;
|
|
97
|
+
const bottomHeight = Math.max(MIN_PANEL_HEIGHT, Math.max(0, activityLog.row - bottomTop));
|
|
98
|
+
const panelWidth = Math.max(MIN_PANEL_WIDTH, Math.floor((cols - (profile === 'compact' ? 6 : 8)) / 2));
|
|
99
|
+
const gap = cols - panelWidth * 2;
|
|
100
|
+
const leftCol = Math.floor(gap / 3);
|
|
101
|
+
const rightCol = leftCol + panelWidth + Math.floor(gap / 3);
|
|
102
|
+
const casperPanel = {
|
|
103
|
+
row: bottomTop,
|
|
104
|
+
col: leftCol,
|
|
105
|
+
width: panelWidth,
|
|
106
|
+
height: bottomHeight,
|
|
107
|
+
};
|
|
108
|
+
const melchiorPanel = {
|
|
109
|
+
row: bottomTop,
|
|
110
|
+
col: rightCol,
|
|
111
|
+
width: panelWidth,
|
|
112
|
+
height: bottomHeight,
|
|
113
|
+
};
|
|
114
|
+
// --- Connectors (Y-shape lines) ---
|
|
115
|
+
const connectors = buildConnectors(balthasarPanel, magiNode, casperPanel, melchiorPanel, mainCenter);
|
|
116
|
+
return {
|
|
117
|
+
profile,
|
|
118
|
+
header,
|
|
119
|
+
verdictStamp,
|
|
120
|
+
balthasarPanel,
|
|
121
|
+
magiNode,
|
|
122
|
+
casperPanel,
|
|
123
|
+
melchiorPanel,
|
|
124
|
+
connectors,
|
|
125
|
+
activityLog,
|
|
126
|
+
statusBar,
|
|
127
|
+
outerFrame,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function buildConnectors(balt, magi, casper, melchior, centerCol) {
|
|
131
|
+
const conns = [];
|
|
132
|
+
// ── BALTHASAR bottom → MAGI top (vertical trunk) ────────────
|
|
133
|
+
const baltBottomRow = balt.row + balt.height;
|
|
134
|
+
// Junction on BALTHASAR bottom border center
|
|
135
|
+
conns.push({ row: baltBottomRow - 1, col: centerCol, char: BOX.bT });
|
|
136
|
+
// Vertical lines between BALTHASAR bottom and MAGI top
|
|
137
|
+
for (let r = baltBottomRow; r < magi.row; r++) {
|
|
138
|
+
conns.push({ row: r, col: centerCol, char: BOX.v });
|
|
139
|
+
}
|
|
140
|
+
// Junction on MAGI top border center (connector enters MAGI from above)
|
|
141
|
+
conns.push({ row: magi.row, col: centerCol, char: BOX.tT });
|
|
142
|
+
// ── MAGI bottom → Y-split (trunk continues down) ───────────
|
|
143
|
+
const magiBottomBorder = magi.row + magi.height - 1;
|
|
144
|
+
const magiBottomRow = magi.row + magi.height;
|
|
145
|
+
// Junction on MAGI bottom border center (connector exits down)
|
|
146
|
+
conns.push({ row: magiBottomBorder, col: centerCol, char: BOX.bT });
|
|
147
|
+
// Vertical lines between MAGI bottom and bottom panels
|
|
148
|
+
for (let r = magiBottomRow; r < casper.row; r++) {
|
|
149
|
+
conns.push({ row: r, col: centerCol, char: BOX.v });
|
|
150
|
+
}
|
|
151
|
+
// ── Y-split into CASPER (left) and MELCHIOR (right) ─────────
|
|
152
|
+
const casperRight = casper.col + casper.width - 1;
|
|
153
|
+
const melchiorLeft = melchior.col;
|
|
154
|
+
const splitRow = casper.row;
|
|
155
|
+
// Horizontal branches at the split row (overwrite panel top borders)
|
|
156
|
+
// Left branch: center → CASPER's top-right
|
|
157
|
+
for (let c = casperRight + 1; c < centerCol; c++) {
|
|
158
|
+
conns.push({ row: splitRow, col: c, char: BOX.h });
|
|
159
|
+
}
|
|
160
|
+
// Junction at CASPER's top-right corner (┐ → ┤ to accept horizontal)
|
|
161
|
+
conns.push({ row: splitRow, col: casperRight, char: BOX.rT });
|
|
162
|
+
// Right branch: center → MELCHIOR's top-left
|
|
163
|
+
for (let c = centerCol + 1; c < melchiorLeft; c++) {
|
|
164
|
+
conns.push({ row: splitRow, col: c, char: BOX.h });
|
|
165
|
+
}
|
|
166
|
+
// Junction at MELCHIOR's top-left corner (┌ → ├ to accept horizontal)
|
|
167
|
+
conns.push({ row: splitRow, col: melchiorLeft, char: BOX.lT });
|
|
168
|
+
// Central split junction — ┼ (cross) because divider continues downward
|
|
169
|
+
conns.push({ row: splitRow, col: centerCol, char: BOX.x });
|
|
170
|
+
return conns;
|
|
171
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MagiTui — Main TUI class that orchestrates the Evangelion-themed interface.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to all 17 MagiEventBus events and drives:
|
|
5
|
+
* Event → State update → Activity log → Animation → Render → ScreenBuffer → stdout
|
|
6
|
+
*/
|
|
7
|
+
import type { MagiEventBus } from '../engine/events.js';
|
|
8
|
+
export interface MagiTuiOptions {
|
|
9
|
+
eventBus: MagiEventBus;
|
|
10
|
+
skipBoot?: boolean;
|
|
11
|
+
stream?: NodeJS.WritableStream;
|
|
12
|
+
soundEnabled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class MagiTui {
|
|
15
|
+
private buf;
|
|
16
|
+
private layout;
|
|
17
|
+
private readonly panelRenderer;
|
|
18
|
+
private readonly headerRenderer;
|
|
19
|
+
private readonly statusBarRenderer;
|
|
20
|
+
private readonly activityLog;
|
|
21
|
+
private readonly animations;
|
|
22
|
+
private readonly stream;
|
|
23
|
+
private readonly eventBus;
|
|
24
|
+
private readonly skipBoot;
|
|
25
|
+
private readonly soundEnabled;
|
|
26
|
+
private unitStates;
|
|
27
|
+
private headerData;
|
|
28
|
+
private statusData;
|
|
29
|
+
private verdictStamp;
|
|
30
|
+
private elapsedTimer?;
|
|
31
|
+
private startTime;
|
|
32
|
+
private renderScheduled;
|
|
33
|
+
private disposed;
|
|
34
|
+
private backgroundFilled;
|
|
35
|
+
private completionPromise?;
|
|
36
|
+
private stdinCleanup?;
|
|
37
|
+
private deregisterCleanup?;
|
|
38
|
+
private dismissResolver?;
|
|
39
|
+
private tuiPhase;
|
|
40
|
+
private overlayUnit?;
|
|
41
|
+
private lastOverlayRect?;
|
|
42
|
+
private connectorPulseIndex;
|
|
43
|
+
private berserkFlashActive;
|
|
44
|
+
private syncRates;
|
|
45
|
+
private terminalFailure;
|
|
46
|
+
private boundListeners;
|
|
47
|
+
private resizeHandler?;
|
|
48
|
+
constructor(options: MagiTuiOptions);
|
|
49
|
+
/** Start the TUI: boot sequence → initial draw → event binding. */
|
|
50
|
+
start(): Promise<void>;
|
|
51
|
+
/** Clean up: stop animations, unbind events, restore terminal. */
|
|
52
|
+
dispose(): void;
|
|
53
|
+
/** Wait for completion animation + keypress before disposing. */
|
|
54
|
+
waitForDismiss(): Promise<void>;
|
|
55
|
+
private bindEvents;
|
|
56
|
+
private on;
|
|
57
|
+
private onDeliberationStart;
|
|
58
|
+
private onPhaseStart;
|
|
59
|
+
private onUnitStart;
|
|
60
|
+
private onUnitComplete;
|
|
61
|
+
private onUnitError;
|
|
62
|
+
private onPhaseSkipped;
|
|
63
|
+
private onPhaseComplete;
|
|
64
|
+
private onDeliberationComplete;
|
|
65
|
+
private onSyncRateUpdated;
|
|
66
|
+
private onBerserkWarning;
|
|
67
|
+
private onBiasDetected;
|
|
68
|
+
private onGospelMilestone;
|
|
69
|
+
private onUmbilicalStatusChanged;
|
|
70
|
+
private onDummyPlugActivated;
|
|
71
|
+
private onDummyPlugRecovery;
|
|
72
|
+
private onCipherDiscovered;
|
|
73
|
+
private onMemoryDriftWarning;
|
|
74
|
+
private onMemoryConsolidated;
|
|
75
|
+
private onBerserkActivated;
|
|
76
|
+
/** Shared berserk flash logic — overlay approach (FIX-03 + FIX-06). */
|
|
77
|
+
private startBerserkFlash;
|
|
78
|
+
private onBerserkDeactivated;
|
|
79
|
+
private onInstrumentalityTriggered;
|
|
80
|
+
private onFusionComplete;
|
|
81
|
+
private onLCLContamination;
|
|
82
|
+
private onLCLPurified;
|
|
83
|
+
private scheduleRender;
|
|
84
|
+
private render;
|
|
85
|
+
private buildPanelContent;
|
|
86
|
+
private buildMagiNodeContent;
|
|
87
|
+
private handleResize;
|
|
88
|
+
private startElapsedTimer;
|
|
89
|
+
private stopElapsedTimer;
|
|
90
|
+
private getOrCreateUnit;
|
|
91
|
+
private getTerminalFailure;
|
|
92
|
+
private renderTerminalWarning;
|
|
93
|
+
private write;
|
|
94
|
+
private handleKeypress;
|
|
95
|
+
/** Resolve pending dismiss promise if in dismiss phase (FIX-02). */
|
|
96
|
+
private resolveDismiss;
|
|
97
|
+
private renderDetailOverlay;
|
|
98
|
+
private playSound;
|
|
99
|
+
private fillBackgroundRect;
|
|
100
|
+
private updateLiveActivityStatus;
|
|
101
|
+
}
|