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,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal output sanitizer — strips control characters that could
|
|
3
|
+
* enable display spoofing, clipboard injection, or cursor manipulation.
|
|
4
|
+
*
|
|
5
|
+
* Removes:
|
|
6
|
+
* - CSI sequences: ESC [ ... (letter or ~) — covers all standard CSI including F-keys
|
|
7
|
+
* - OSC: ESC ] ... (BEL | ESC \)
|
|
8
|
+
* - DCS/APC/PM/SOS: ESC (P|_|^|X) ... (BEL | ESC \)
|
|
9
|
+
* - 2-char ESC sequences: ESC + single letter (e.g., ESC c = RIS, ESC 7/8 = save/restore)
|
|
10
|
+
* - Charset designation: ESC ( B, ESC ) 0, etc.
|
|
11
|
+
* - Bare control chars: NUL, BEL, standalone CR (not followed by LF)
|
|
12
|
+
* Preserves: printable text, newlines (\n), tabs (\t).
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeForTerminal(s: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal output sanitizer — strips control characters that could
|
|
3
|
+
* enable display spoofing, clipboard injection, or cursor manipulation.
|
|
4
|
+
*
|
|
5
|
+
* Removes:
|
|
6
|
+
* - CSI sequences: ESC [ ... (letter or ~) — covers all standard CSI including F-keys
|
|
7
|
+
* - OSC: ESC ] ... (BEL | ESC \)
|
|
8
|
+
* - DCS/APC/PM/SOS: ESC (P|_|^|X) ... (BEL | ESC \)
|
|
9
|
+
* - 2-char ESC sequences: ESC + single letter (e.g., ESC c = RIS, ESC 7/8 = save/restore)
|
|
10
|
+
* - Charset designation: ESC ( B, ESC ) 0, etc.
|
|
11
|
+
* - Bare control chars: NUL, BEL, standalone CR (not followed by LF)
|
|
12
|
+
* Preserves: printable text, newlines (\n), tabs (\t).
|
|
13
|
+
*/
|
|
14
|
+
const CONTROL_RE =
|
|
15
|
+
// eslint-disable-next-line no-control-regex
|
|
16
|
+
/\x1b(?:\[[0-9;?]*[A-Za-z~]|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[P_^X][^\x07\x1b]*(?:\x07|\x1b\\)?|[()][A-Za-z0-9]|[A-Za-z0-9=<>])|[\x00\x07\x0d](?!\x0a)/g;
|
|
17
|
+
export function sanitizeForTerminal(s) {
|
|
18
|
+
return s.replace(CONTROL_RE, '');
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MagiDeliberation, MagiOpinion, DeliberationRound } from '../types/core.js';
|
|
2
|
+
import type { ConsensusResult } from '../types/consensus.js';
|
|
3
|
+
export declare function printHeader(): void;
|
|
4
|
+
export declare function printRound(round: DeliberationRound): void;
|
|
5
|
+
export declare function printOpinion(opinion: MagiOpinion): void;
|
|
6
|
+
export declare function printConsensus(consensus: ConsensusResult): void;
|
|
7
|
+
export declare function printDeliberation(deliberation: MagiDeliberation): void;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
const UNIT_COLORS = {
|
|
3
|
+
MELCHIOR: chalk.blue,
|
|
4
|
+
BALTHASAR: chalk.green,
|
|
5
|
+
CASPER: chalk.magenta,
|
|
6
|
+
};
|
|
7
|
+
const VOTE_COLORS = {
|
|
8
|
+
APPROVE: chalk.green.bold,
|
|
9
|
+
REJECT: chalk.red.bold,
|
|
10
|
+
ABSTAIN: chalk.gray,
|
|
11
|
+
};
|
|
12
|
+
const DECISION_COLORS = {
|
|
13
|
+
UNANIMOUS_APPROVE: chalk.bgGreen.black.bold,
|
|
14
|
+
MAJORITY_APPROVE: chalk.green.bold,
|
|
15
|
+
UNANIMOUS_REJECT: chalk.bgRed.white.bold,
|
|
16
|
+
MAJORITY_REJECT: chalk.red.bold,
|
|
17
|
+
DEADLOCK: chalk.bgYellow.black.bold,
|
|
18
|
+
INSUFFICIENT: chalk.bgGray.white,
|
|
19
|
+
};
|
|
20
|
+
export function printHeader() {
|
|
21
|
+
console.log('');
|
|
22
|
+
console.log(chalk.cyan.bold(' ╔══════════════════════════════════════╗'));
|
|
23
|
+
console.log(chalk.cyan.bold(' ║ M A G I S Y S T E M ║'));
|
|
24
|
+
console.log(chalk.cyan.bold(' ║ Multi-AI Deliberation Framework ║'));
|
|
25
|
+
console.log(chalk.cyan.bold(' ╚══════════════════════════════════════╝'));
|
|
26
|
+
console.log('');
|
|
27
|
+
}
|
|
28
|
+
export function printRound(round) {
|
|
29
|
+
console.log(chalk.yellow(`\n━━━ Round ${round.roundNumber}: ${round.phase.toUpperCase()} ━━━\n`));
|
|
30
|
+
for (const opinion of round.opinions) {
|
|
31
|
+
printOpinion(opinion);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function printOpinion(opinion) {
|
|
35
|
+
const unitColor = UNIT_COLORS[opinion.unit] ?? chalk.white;
|
|
36
|
+
const voteColor = VOTE_COLORS[opinion.vote] ?? chalk.white;
|
|
37
|
+
console.log(unitColor(` ┌─ ${opinion.unit} ─────────────────────`));
|
|
38
|
+
console.log(unitColor(` │`) + ` Vote: ${voteColor(opinion.vote)} (confidence: ${opinion.confidence.toFixed(2)})`);
|
|
39
|
+
console.log(unitColor(` │`) + ` ${opinion.reasoning.slice(0, 200)}${opinion.reasoning.length > 200 ? '...' : ''}`);
|
|
40
|
+
if (opinion.keyPoints.length > 0) {
|
|
41
|
+
for (const point of opinion.keyPoints.slice(0, 3)) {
|
|
42
|
+
console.log(unitColor(` │`) + chalk.dim(` • ${point}`));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
console.log(unitColor(` └──────────────────────────────────`));
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
export function printConsensus(consensus) {
|
|
49
|
+
const decisionColor = DECISION_COLORS[consensus.decision] ?? chalk.white;
|
|
50
|
+
console.log(chalk.yellow('\n━━━ MAGI CONSENSUS ━━━━━━━━━━━━━━━━━━━\n'));
|
|
51
|
+
console.log(` Decision: ${decisionColor(` ${consensus.decision.replace(/_/g, ' ')} `)}`);
|
|
52
|
+
console.log(` Method: ${consensus.method}`);
|
|
53
|
+
console.log(` Confidence: ${(consensus.confidence * 100).toFixed(0)}%`);
|
|
54
|
+
console.log('');
|
|
55
|
+
console.log(` APPROVE: ${consensus.votes.approve.join(', ') || 'none'}`);
|
|
56
|
+
console.log(` REJECT: ${consensus.votes.reject.join(', ') || 'none'}`);
|
|
57
|
+
console.log(` ABSTAIN: ${consensus.votes.abstain.join(', ') || 'none'}`);
|
|
58
|
+
if (consensus.dissent && consensus.dissent.length > 0) {
|
|
59
|
+
console.log(chalk.yellow('\n Dissenting opinions:'));
|
|
60
|
+
for (const d of consensus.dissent) {
|
|
61
|
+
console.log(chalk.dim(` ${d.unit}: ${d.reasoning.slice(0, 100)}...`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log(chalk.yellow('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
65
|
+
}
|
|
66
|
+
export function printDeliberation(deliberation) {
|
|
67
|
+
printHeader();
|
|
68
|
+
console.log(chalk.dim(` Task: ${deliberation.task.title}`));
|
|
69
|
+
console.log(chalk.dim(` Type: ${deliberation.task.type}`));
|
|
70
|
+
console.log(chalk.dim(` ID: ${deliberation.id}`));
|
|
71
|
+
for (const round of deliberation.rounds) {
|
|
72
|
+
printRound(round);
|
|
73
|
+
}
|
|
74
|
+
printConsensus(deliberation.consensus);
|
|
75
|
+
console.log(chalk.dim(` Duration: ${(deliberation.totalDurationMs / 1000).toFixed(1)}s`));
|
|
76
|
+
console.log(chalk.dim(` Rounds: ${deliberation.rounds.length}`));
|
|
77
|
+
console.log('');
|
|
78
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export function formatDeliberationMarkdown(deliberation) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
lines.push(`# MAGI Deliberation Report`);
|
|
4
|
+
lines.push('');
|
|
5
|
+
lines.push(`- **Task:** ${deliberation.task.title}`);
|
|
6
|
+
lines.push(`- **Type:** ${deliberation.task.type}`);
|
|
7
|
+
lines.push(`- **ID:** ${deliberation.id}`);
|
|
8
|
+
lines.push(`- **Duration:** ${(deliberation.totalDurationMs / 1000).toFixed(1)}s`);
|
|
9
|
+
lines.push(`- **Decision:** ${deliberation.consensus.decision}`);
|
|
10
|
+
lines.push('');
|
|
11
|
+
for (const round of deliberation.rounds) {
|
|
12
|
+
lines.push(formatRound(round));
|
|
13
|
+
}
|
|
14
|
+
lines.push(formatConsensus(deliberation.consensus));
|
|
15
|
+
return lines.join('\n');
|
|
16
|
+
}
|
|
17
|
+
function formatRound(round) {
|
|
18
|
+
const lines = [];
|
|
19
|
+
lines.push(`## Round ${round.roundNumber}: ${round.phase}`);
|
|
20
|
+
lines.push('');
|
|
21
|
+
for (const opinion of round.opinions) {
|
|
22
|
+
lines.push(formatOpinion(opinion));
|
|
23
|
+
}
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
function formatOpinion(opinion) {
|
|
27
|
+
const lines = [];
|
|
28
|
+
lines.push(`### ${opinion.unit}`);
|
|
29
|
+
lines.push('');
|
|
30
|
+
lines.push(`- **Vote:** ${opinion.vote} (confidence: ${opinion.confidence.toFixed(2)})`);
|
|
31
|
+
lines.push(`- **Reasoning:** ${opinion.reasoning}`);
|
|
32
|
+
if (opinion.keyPoints.length > 0) {
|
|
33
|
+
lines.push('- **Key Points:**');
|
|
34
|
+
for (const point of opinion.keyPoints) {
|
|
35
|
+
lines.push(` - ${point}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (opinion.suggestions && opinion.suggestions.length > 0) {
|
|
39
|
+
lines.push('- **Suggestions:**');
|
|
40
|
+
for (const s of opinion.suggestions) {
|
|
41
|
+
lines.push(` - ${s}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
lines.push('');
|
|
45
|
+
return lines.join('\n');
|
|
46
|
+
}
|
|
47
|
+
function formatConsensus(consensus) {
|
|
48
|
+
const lines = [];
|
|
49
|
+
lines.push('## Consensus');
|
|
50
|
+
lines.push('');
|
|
51
|
+
lines.push(`- **Decision:** ${consensus.decision}`);
|
|
52
|
+
lines.push(`- **Method:** ${consensus.method}`);
|
|
53
|
+
lines.push(`- **Confidence:** ${(consensus.confidence * 100).toFixed(0)}%`);
|
|
54
|
+
lines.push(`- **Approve:** ${consensus.votes.approve.join(', ') || 'none'}`);
|
|
55
|
+
lines.push(`- **Reject:** ${consensus.votes.reject.join(', ') || 'none'}`);
|
|
56
|
+
lines.push(`- **Abstain:** ${consensus.votes.abstain.join(', ') || 'none'}`);
|
|
57
|
+
if (consensus.dissent && consensus.dissent.length > 0) {
|
|
58
|
+
lines.push('');
|
|
59
|
+
lines.push('### Dissenting Opinions');
|
|
60
|
+
for (const d of consensus.dissent) {
|
|
61
|
+
lines.push(`- **${d.unit}:** ${d.reasoning}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return lines.join('\n');
|
|
65
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MagiEventBus } from '../engine/events.js';
|
|
2
|
+
/**
|
|
3
|
+
* Real-time streaming reporter that listens to MagiEventBus
|
|
4
|
+
* and displays progress as events arrive.
|
|
5
|
+
*
|
|
6
|
+
* In non-TTY mode (CI/pipe), falls back to plain log lines.
|
|
7
|
+
*
|
|
8
|
+
* Call `dispose()` to remove all event listeners.
|
|
9
|
+
*/
|
|
10
|
+
export declare class StreamingProgressReporter {
|
|
11
|
+
private readonly isTTY;
|
|
12
|
+
private unitTimers;
|
|
13
|
+
private readonly bus;
|
|
14
|
+
private readonly registrations;
|
|
15
|
+
constructor(eventBus: MagiEventBus);
|
|
16
|
+
/** Remove all event listeners registered by this reporter. */
|
|
17
|
+
dispose(): void;
|
|
18
|
+
private track;
|
|
19
|
+
private bind;
|
|
20
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { detectOutputMode } from '../utils/tty.js';
|
|
3
|
+
import { unitChalk, EVA_PALETTE } from '../tui/colors.js';
|
|
4
|
+
const { approve, reject, abstain } = EVA_PALETTE;
|
|
5
|
+
const VOTE_ICONS = {
|
|
6
|
+
APPROVE: chalk.rgb(approve.r, approve.g, approve.b)('APPROVE'),
|
|
7
|
+
REJECT: chalk.rgb(reject.r, reject.g, reject.b)('REJECT'),
|
|
8
|
+
ABSTAIN: chalk.rgb(abstain.r, abstain.g, abstain.b)('ABSTAIN'),
|
|
9
|
+
};
|
|
10
|
+
function colorUnit(unit) {
|
|
11
|
+
return unitChalk(unit)(unit);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Real-time streaming reporter that listens to MagiEventBus
|
|
15
|
+
* and displays progress as events arrive.
|
|
16
|
+
*
|
|
17
|
+
* In non-TTY mode (CI/pipe), falls back to plain log lines.
|
|
18
|
+
*
|
|
19
|
+
* Call `dispose()` to remove all event listeners.
|
|
20
|
+
*/
|
|
21
|
+
export class StreamingProgressReporter {
|
|
22
|
+
isTTY;
|
|
23
|
+
unitTimers = new Map();
|
|
24
|
+
bus;
|
|
25
|
+
// Store handler references for cleanup — use Function to avoid variance issues
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
27
|
+
registrations = [];
|
|
28
|
+
constructor(eventBus) {
|
|
29
|
+
this.isTTY = detectOutputMode() === 'interactive';
|
|
30
|
+
this.bus = eventBus;
|
|
31
|
+
this.bind();
|
|
32
|
+
}
|
|
33
|
+
/** Remove all event listeners registered by this reporter. */
|
|
34
|
+
dispose() {
|
|
35
|
+
for (const { event, handler } of this.registrations) {
|
|
36
|
+
// removeListener accepts Function via underlying EventEmitter
|
|
37
|
+
this.bus.removeListener(event, handler);
|
|
38
|
+
}
|
|
39
|
+
this.registrations.length = 0;
|
|
40
|
+
this.unitTimers.clear();
|
|
41
|
+
}
|
|
42
|
+
track(event, handler) {
|
|
43
|
+
this.registrations.push({ event, handler });
|
|
44
|
+
this.bus.on(event, handler);
|
|
45
|
+
}
|
|
46
|
+
bind() {
|
|
47
|
+
this.track('deliberation:start', (e) => {
|
|
48
|
+
if (this.isTTY) {
|
|
49
|
+
console.error(chalk.cyan(` Deliberation started: ${e.taskType} — ${e.taskTitle}`));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.error(`[MAGI] start: ${e.taskType} — ${e.taskTitle}`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
this.track('phase:start', (e) => {
|
|
56
|
+
if (this.isTTY) {
|
|
57
|
+
console.error(chalk.cyan(`\n Phase ${e.roundNumber}: ${e.phase}`));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error(`[MAGI] phase: ${e.phase} (round ${e.roundNumber})`);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
this.track('unit:start', (e) => {
|
|
64
|
+
this.unitTimers.set(e.unit, Date.now());
|
|
65
|
+
if (this.isTTY) {
|
|
66
|
+
console.error(chalk.gray(` ${colorUnit(e.unit)} thinking...`));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
this.track('unit:complete', (e) => {
|
|
70
|
+
const elapsed = Date.now() - (this.unitTimers.get(e.unit) ?? Date.now());
|
|
71
|
+
const vote = VOTE_ICONS[e.vote] ?? e.vote;
|
|
72
|
+
const conf = `${(e.confidence * 100).toFixed(0)}%`;
|
|
73
|
+
if (this.isTTY) {
|
|
74
|
+
console.error(` ${colorUnit(e.unit)} ${vote} (${conf}) [${elapsed}ms]`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.error(`[MAGI] ${e.unit}: ${e.vote} (${conf}) [${elapsed}ms]`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
this.track('unit:error', (e) => {
|
|
81
|
+
if (this.isTTY) {
|
|
82
|
+
console.error(chalk.red(` ${colorUnit(e.unit)} FAILED — ${e.error.slice(0, 80)}`));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.error(`[MAGI] ${e.unit}: FAILED — ${e.error.slice(0, 80)}`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
this.track('phase:skipped', (e) => {
|
|
89
|
+
const label = e.reason === 'unanimous_early_exit' ? 'unanimous' : 'majority';
|
|
90
|
+
if (this.isTTY) {
|
|
91
|
+
console.error(chalk.yellow(`\n Phase skipped: ${e.phase} (${label} early exit)`));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.error(`[MAGI] phase skipped: ${e.phase} (${label})`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
this.track('deliberation:complete', (e) => {
|
|
98
|
+
if (this.isTTY) {
|
|
99
|
+
console.error(chalk.bold(`\n MAGI DECISION: ${e.decision} (${e.rounds} rounds, ${e.totalDurationMs}ms)`));
|
|
100
|
+
if (e.fromCache)
|
|
101
|
+
console.error(chalk.gray(' (from cache)'));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.error(`[MAGI] decision: ${e.decision} (${e.rounds} rounds, ${e.totalDurationMs}ms)`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Phase H events
|
|
108
|
+
this.track('syncrate:updated', (e) => {
|
|
109
|
+
const rateStr = Object.entries(e.rates)
|
|
110
|
+
.map(([unit, rate]) => `${unit} ${(rate * 100).toFixed(1)}%`)
|
|
111
|
+
.join(' | ');
|
|
112
|
+
if (this.isTTY) {
|
|
113
|
+
console.error(chalk.cyan(` シンクロ率: ${rateStr}`));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.error(`[MAGI] syncrate: ${rateStr}`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
this.track('berserk:warning', (e) => {
|
|
120
|
+
const msg = `暴走警告: 合計シンクロ率 ${e.totalSyncRate.toFixed(2)} > ${e.threshold}`;
|
|
121
|
+
if (this.isTTY) {
|
|
122
|
+
console.error(chalk.red.bold(` [BERSERK] ${msg}`));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.error(`[MAGI] BERSERK: ${msg}`);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
this.track('bias:detected', (e) => {
|
|
129
|
+
if (e.level !== 1) {
|
|
130
|
+
const levelStr = e.level === 'MAX' ? 'MAX' : `Level ${e.level}`;
|
|
131
|
+
if (this.isTTY) {
|
|
132
|
+
console.error(chalk.yellow(` [A.T. FIELD ${levelStr}] バイアス検出 (エントロピー: ${e.voteEntropy.toFixed(3)})`));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.error(`[MAGI] AT-FIELD: ${levelStr} (entropy: ${e.voteEntropy.toFixed(3)})`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
this.track('gospel:milestone', (e) => {
|
|
140
|
+
const labels = {
|
|
141
|
+
first_deliberation: '最初の審議完了',
|
|
142
|
+
first_unanimous: '初の全会一致',
|
|
143
|
+
first_deadlock: '初のデッドロック',
|
|
144
|
+
centenary: '100回到達',
|
|
145
|
+
millennium: '1000回到達',
|
|
146
|
+
};
|
|
147
|
+
const label = labels[e.milestone] ?? e.milestone;
|
|
148
|
+
if (this.isTTY) {
|
|
149
|
+
console.error(chalk.yellow.bold(` [GOSPEL] ${label} (第${e.count}審議)`));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.error(`[MAGI] GOSPEL: ${label} (#${e.count})`);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
this.track('umbilical:status_changed', (e) => {
|
|
156
|
+
const statusColors = {
|
|
157
|
+
connected: chalk.green,
|
|
158
|
+
degraded: chalk.yellow,
|
|
159
|
+
disconnected: chalk.red,
|
|
160
|
+
};
|
|
161
|
+
const colorFn = statusColors[e.newStatus] ?? chalk.white;
|
|
162
|
+
if (this.isTTY) {
|
|
163
|
+
console.error(` [CABLE] ${colorUnit(e.unit)} ${e.previousStatus} → ${colorFn(e.newStatus)}`);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.error(`[MAGI] CABLE: ${e.unit} ${e.previousStatus} -> ${e.newStatus}`);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
this.track('dummyplug:activated', (e) => {
|
|
170
|
+
if (this.isTTY) {
|
|
171
|
+
console.error(chalk.magenta(` [DUMMY PLUG] ${colorUnit(e.unit)} 起動 (confidence: ${(e.confidence * 100).toFixed(0)}%, samples: ${e.profileSamples})`));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.error(`[MAGI] DUMMY-PLUG: ${e.unit} activated (confidence: ${(e.confidence * 100).toFixed(0)}%)`);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrolling activity log displayed above the status bar.
|
|
3
|
+
* Shows recent events with ▶ prefix.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScreenBuffer } from './screen-buffer.js';
|
|
6
|
+
import type { Rect } from './layout.js';
|
|
7
|
+
import { type RGBColor } from './colors.js';
|
|
8
|
+
export declare class ActivityLog {
|
|
9
|
+
private entries;
|
|
10
|
+
private liveEntry?;
|
|
11
|
+
private readonly maxLines;
|
|
12
|
+
constructor(maxLines: number);
|
|
13
|
+
/** Add a log entry. Oldest entries are discarded when full. */
|
|
14
|
+
push(message: string, color?: RGBColor): void;
|
|
15
|
+
/** Set or clear the live status line shown at the bottom of the log area. */
|
|
16
|
+
setLive(message?: string, color?: RGBColor): void;
|
|
17
|
+
/** Draw the log entries into the screen buffer. */
|
|
18
|
+
draw(buf: ScreenBuffer, rect: Rect): void;
|
|
19
|
+
/** Clear all entries. */
|
|
20
|
+
clear(): void;
|
|
21
|
+
/** Get current entry count. */
|
|
22
|
+
get length(): number;
|
|
23
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrolling activity log displayed above the status bar.
|
|
3
|
+
* Shows recent events with ▶ prefix.
|
|
4
|
+
*/
|
|
5
|
+
import { truncateToDisplayWidth } from './screen-buffer.js';
|
|
6
|
+
import { EVA_PALETTE } from './colors.js';
|
|
7
|
+
// ── Activity Log ────────────────────────────────────────────
|
|
8
|
+
export class ActivityLog {
|
|
9
|
+
entries = [];
|
|
10
|
+
liveEntry;
|
|
11
|
+
maxLines;
|
|
12
|
+
constructor(maxLines) {
|
|
13
|
+
this.maxLines = maxLines;
|
|
14
|
+
}
|
|
15
|
+
/** Add a log entry. Oldest entries are discarded when full. */
|
|
16
|
+
push(message, color) {
|
|
17
|
+
this.entries.push({ message, color: color ?? EVA_PALETTE.textPrimary });
|
|
18
|
+
if (this.entries.length > this.maxLines) {
|
|
19
|
+
this.entries.shift();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Set or clear the live status line shown at the bottom of the log area. */
|
|
23
|
+
setLive(message, color) {
|
|
24
|
+
if (!message) {
|
|
25
|
+
this.liveEntry = undefined;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
this.liveEntry = { message, color: color ?? EVA_PALETTE.magi };
|
|
29
|
+
}
|
|
30
|
+
/** Draw the log entries into the screen buffer. */
|
|
31
|
+
draw(buf, rect) {
|
|
32
|
+
const { row, col, width, height } = rect;
|
|
33
|
+
const maxWidth = width - 4; // 2 for borders + 2 for "▶ " prefix
|
|
34
|
+
const historyRows = this.liveEntry ? Math.max(0, height - 1) : height;
|
|
35
|
+
for (let i = 0; i < height; i++) {
|
|
36
|
+
const y = row + i;
|
|
37
|
+
// Clear line
|
|
38
|
+
for (let x = col + 1; x < col + width - 1; x++) {
|
|
39
|
+
buf.writeAt(y, x, ' ');
|
|
40
|
+
}
|
|
41
|
+
if (this.liveEntry && i === height - 1) {
|
|
42
|
+
const liveColor = this.liveEntry.color;
|
|
43
|
+
buf.writeAt(y, col + 2, '▷', EVA_PALETTE.magi.r, EVA_PALETTE.magi.g, EVA_PALETTE.magi.b);
|
|
44
|
+
const liveMsg = truncateToDisplayWidth(this.liveEntry.message, maxWidth - 2);
|
|
45
|
+
buf.writeAt(y, col + 4, liveMsg, liveColor.r, liveColor.g, liveColor.b);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const entryIdx = this.entries.length - historyRows + i;
|
|
49
|
+
if (i < historyRows && entryIdx >= 0 && entryIdx < this.entries.length) {
|
|
50
|
+
const entry = this.entries[entryIdx];
|
|
51
|
+
const c = entry.color;
|
|
52
|
+
buf.writeAt(y, col + 2, '▶', EVA_PALETTE.frame.r, EVA_PALETTE.frame.g, EVA_PALETTE.frame.b);
|
|
53
|
+
const msg = truncateToDisplayWidth(entry.message, maxWidth - 2);
|
|
54
|
+
buf.writeAt(y, col + 4, msg, c.r, c.g, c.b);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Clear all entries. */
|
|
59
|
+
clear() {
|
|
60
|
+
this.entries = [];
|
|
61
|
+
this.liveEntry = undefined;
|
|
62
|
+
}
|
|
63
|
+
/** Get current entry count. */
|
|
64
|
+
get length() {
|
|
65
|
+
return this.entries.length;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animation controller for TUI effects.
|
|
3
|
+
* Manages breathing, cascade, flash, and overlay animations.
|
|
4
|
+
*/
|
|
5
|
+
import type { ConsensusDecision } from '../types/consensus.js';
|
|
6
|
+
type FrameCallback = (value: number) => void;
|
|
7
|
+
type PulseCallback = (index: number) => void;
|
|
8
|
+
export declare class AnimationController {
|
|
9
|
+
private timers;
|
|
10
|
+
private disposed;
|
|
11
|
+
/**
|
|
12
|
+
* Start breathing animation for a unit.
|
|
13
|
+
* Calls onFrame with a phase value (0.0 ~ 1.0) cycling at ~16fps.
|
|
14
|
+
*/
|
|
15
|
+
startBreathing(unitId: string, onFrame: FrameCallback): void;
|
|
16
|
+
startBreathingWithOffset(unitId: string, phaseOffset: number, onFrame: FrameCallback): void;
|
|
17
|
+
/** Stop breathing animation for a unit. */
|
|
18
|
+
stopBreathing(unitId: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Cascade reveal: call onReveal for each unit with a staggered delay.
|
|
21
|
+
* Returns a promise that resolves when all reveals are done.
|
|
22
|
+
*/
|
|
23
|
+
cascade(units: string[], onReveal: (unit: string) => void): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* BERSERK flash: toggle red flash on/off multiple times.
|
|
26
|
+
*/
|
|
27
|
+
berserkFlash(onFlash: (isRed: boolean) => void): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* UNANIMOUS reveal: show overlay text after a brief pause.
|
|
30
|
+
*/
|
|
31
|
+
unanimousReveal(decision: ConsensusDecision, onOverlay: (text: string, isApprove: boolean) => void): Promise<void>;
|
|
32
|
+
verdictLock(decision: ConsensusDecision, onOverlay: (text: string, tone: 'approve' | 'reject' | 'deadlock', blink: boolean) => void): Promise<void>;
|
|
33
|
+
linePulse(length: number, onPulse: PulseCallback): Promise<void>;
|
|
34
|
+
/** Stop all animations and prevent new ones. */
|
|
35
|
+
dispose(): void;
|
|
36
|
+
/** Check if a breathing animation is active. */
|
|
37
|
+
isBreathing(unitId: string): boolean;
|
|
38
|
+
}
|
|
39
|
+
export {};
|