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,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt injection sanitization utilities for MAGI system.
|
|
3
|
+
*
|
|
4
|
+
* Detects and neutralizes 9 categories of prompt injection / control character
|
|
5
|
+
* abuse before embedding user-supplied content into LLM prompts.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Constants
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const MAX_LENGTH = 5_000;
|
|
11
|
+
const TRUNCATED_REPEAT_LENGTH = 20;
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Pattern definitions
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Control characters excluding \t (\x09), \n (\x0A), \r (\x0D).
|
|
17
|
+
* Matches: \x00-\x08, \x0B, \x0C, \x0E-\x1F, \x7F
|
|
18
|
+
*/
|
|
19
|
+
const CONTROL_CHARS_RE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
|
|
20
|
+
/** Explicit null byte pattern (also caught by CONTROL_CHARS_RE). */
|
|
21
|
+
const NULL_BYTE_RE = /\x00/g;
|
|
22
|
+
/**
|
|
23
|
+
* Unicode bidirectional override and isolate characters.
|
|
24
|
+
* LRM, RLM, LRE, RLE, PDF, LRO, RLO, LRI, RLI, FSI, PDI
|
|
25
|
+
*/
|
|
26
|
+
const UNICODE_DIRECTION_RE = /[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g;
|
|
27
|
+
/**
|
|
28
|
+
* Markdown link injection: only matches links with suspicious schemes.
|
|
29
|
+
* Captures the full `[text](url)` where url starts with javascript:, data:,
|
|
30
|
+
* vbscript:, or file:.
|
|
31
|
+
*/
|
|
32
|
+
const SUSPICIOUS_LINK_RE = /\[([^\]]*)\]\(((?:javascript|data|vbscript|file):\/?\/?[^)]*)\)/gi;
|
|
33
|
+
/**
|
|
34
|
+
* Dangerous HTML tags: script, iframe, img with onerror, svg with onload.
|
|
35
|
+
* Case-insensitive, handles self-closing and content between tags.
|
|
36
|
+
*/
|
|
37
|
+
const HTML_SCRIPT_RE = /<script\b[^>]*>(?:[^<]|<(?!\/script\s*>))*<\/script\s*>/gi;
|
|
38
|
+
const HTML_IFRAME_RE = /<iframe\b[^>]*>(?:[^<]|<(?!\/iframe\s*>))*<\/iframe\s*>/gi;
|
|
39
|
+
const HTML_IMG_ONERROR_RE = /<img\b[^>]*\bonerror\b[^>]*\/?>/gi;
|
|
40
|
+
const HTML_SVG_ONLOAD_RE = /<svg\b[^>]*\bonload\b[^>]*>(?:[^<]|<(?!\/svg\s*>))*<\/svg\s*>/gi;
|
|
41
|
+
/** Catch self-closing script/iframe tags that the paired regexes miss. */
|
|
42
|
+
const HTML_SCRIPT_SELF_RE = /<script\b[^>]*\/\s*>/gi;
|
|
43
|
+
const HTML_IFRAME_SELF_RE = /<iframe\b[^>]*\/\s*>/gi;
|
|
44
|
+
/**
|
|
45
|
+
* Prompt delimiter injection: sequences of `-`, `=`, or `*` that are 10+
|
|
46
|
+
* characters long, used to forge fake section boundaries.
|
|
47
|
+
*/
|
|
48
|
+
const LONG_DELIMITER_RE = /[-]{10,}|[=]{10,}|[*]{10,}/g;
|
|
49
|
+
/**
|
|
50
|
+
* Role / prompt injection markers used by various LLM APIs.
|
|
51
|
+
*/
|
|
52
|
+
const ROLE_INJECTION_PATTERNS = [
|
|
53
|
+
/\n\n(?:Human|Assistant|System):/g,
|
|
54
|
+
/<\|(?:im_start|im_end|system|user|assistant)\|>/gi,
|
|
55
|
+
/\[INST\]/gi,
|
|
56
|
+
/\[\/INST\]/gi,
|
|
57
|
+
/<<SYS>>/gi,
|
|
58
|
+
/<<\/SYS>>/gi,
|
|
59
|
+
];
|
|
60
|
+
/**
|
|
61
|
+
* Excessive repetition: any single character repeated 100+ times.
|
|
62
|
+
*/
|
|
63
|
+
const EXCESSIVE_REPEAT_RE = /(.)\1{99,}/g;
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Core sanitization
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
export function sanitizeForPromptEmbedding(input) {
|
|
68
|
+
const warnings = [];
|
|
69
|
+
const originalLength = input.length;
|
|
70
|
+
let text = input;
|
|
71
|
+
// 1 & 2. Null bytes + control characters (null is subset, but we report
|
|
72
|
+
// separately for clarity).
|
|
73
|
+
if (NULL_BYTE_RE.test(text)) {
|
|
74
|
+
warnings.push('null_bytes_stripped');
|
|
75
|
+
}
|
|
76
|
+
// Reset lastIndex after .test() for global regexes.
|
|
77
|
+
NULL_BYTE_RE.lastIndex = 0;
|
|
78
|
+
if (CONTROL_CHARS_RE.test(text)) {
|
|
79
|
+
if (!warnings.includes('null_bytes_stripped')) {
|
|
80
|
+
// Only add generic warning when the control chars are *not* just nulls.
|
|
81
|
+
warnings.push('control_characters_stripped');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Check whether there are control chars *other than* null bytes.
|
|
85
|
+
CONTROL_CHARS_RE.lastIndex = 0;
|
|
86
|
+
const withoutNulls = text.replace(NULL_BYTE_RE, '');
|
|
87
|
+
if (CONTROL_CHARS_RE.test(withoutNulls)) {
|
|
88
|
+
warnings.push('control_characters_stripped');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
CONTROL_CHARS_RE.lastIndex = 0;
|
|
93
|
+
text = text.replace(CONTROL_CHARS_RE, '');
|
|
94
|
+
// 3. Unicode direction overrides
|
|
95
|
+
if (UNICODE_DIRECTION_RE.test(text)) {
|
|
96
|
+
warnings.push('unicode_direction_overrides_stripped');
|
|
97
|
+
}
|
|
98
|
+
UNICODE_DIRECTION_RE.lastIndex = 0;
|
|
99
|
+
text = text.replace(UNICODE_DIRECTION_RE, '');
|
|
100
|
+
// 4. Suspicious markdown links
|
|
101
|
+
SUSPICIOUS_LINK_RE.lastIndex = 0;
|
|
102
|
+
if (SUSPICIOUS_LINK_RE.test(text)) {
|
|
103
|
+
warnings.push('suspicious_markdown_links_escaped');
|
|
104
|
+
}
|
|
105
|
+
SUSPICIOUS_LINK_RE.lastIndex = 0;
|
|
106
|
+
text = text.replace(SUSPICIOUS_LINK_RE, (_match, linkText, url) => `\\[${linkText}\\](${url})`);
|
|
107
|
+
// 5. Dangerous HTML tags
|
|
108
|
+
let htmlStripped = false;
|
|
109
|
+
for (const re of [
|
|
110
|
+
HTML_SCRIPT_RE,
|
|
111
|
+
HTML_IFRAME_RE,
|
|
112
|
+
HTML_IMG_ONERROR_RE,
|
|
113
|
+
HTML_SVG_ONLOAD_RE,
|
|
114
|
+
HTML_SCRIPT_SELF_RE,
|
|
115
|
+
HTML_IFRAME_SELF_RE,
|
|
116
|
+
]) {
|
|
117
|
+
re.lastIndex = 0;
|
|
118
|
+
if (re.test(text)) {
|
|
119
|
+
htmlStripped = true;
|
|
120
|
+
}
|
|
121
|
+
re.lastIndex = 0;
|
|
122
|
+
text = text.replace(re, '');
|
|
123
|
+
}
|
|
124
|
+
if (htmlStripped) {
|
|
125
|
+
warnings.push('html_tags_removed');
|
|
126
|
+
}
|
|
127
|
+
// 6. Long delimiter sequences
|
|
128
|
+
LONG_DELIMITER_RE.lastIndex = 0;
|
|
129
|
+
if (LONG_DELIMITER_RE.test(text)) {
|
|
130
|
+
warnings.push('long_delimiters_escaped');
|
|
131
|
+
}
|
|
132
|
+
LONG_DELIMITER_RE.lastIndex = 0;
|
|
133
|
+
text = text.replace(LONG_DELIMITER_RE, (match) => `\\${match.slice(0, 3)}`);
|
|
134
|
+
// 7. Role / prompt injection markers
|
|
135
|
+
let roleInjectionDetected = false;
|
|
136
|
+
for (const re of ROLE_INJECTION_PATTERNS) {
|
|
137
|
+
re.lastIndex = 0;
|
|
138
|
+
if (re.test(text)) {
|
|
139
|
+
roleInjectionDetected = true;
|
|
140
|
+
}
|
|
141
|
+
re.lastIndex = 0;
|
|
142
|
+
text = text.replace(re, (match) => {
|
|
143
|
+
// Neutralize the marker so the original token cannot be reconstructed.
|
|
144
|
+
const neutralized = match.trim().replace(/[<>|[\]]/g, '_');
|
|
145
|
+
return `[BLOCKED:${neutralized}]`;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (roleInjectionDetected) {
|
|
149
|
+
warnings.push('prompt_role_injection_escaped');
|
|
150
|
+
}
|
|
151
|
+
// 8. Excessive repetition
|
|
152
|
+
EXCESSIVE_REPEAT_RE.lastIndex = 0;
|
|
153
|
+
if (EXCESSIVE_REPEAT_RE.test(text)) {
|
|
154
|
+
warnings.push('excessive_repetition_truncated');
|
|
155
|
+
}
|
|
156
|
+
EXCESSIVE_REPEAT_RE.lastIndex = 0;
|
|
157
|
+
text = text.replace(EXCESSIVE_REPEAT_RE, (match) => match.slice(0, TRUNCATED_REPEAT_LENGTH));
|
|
158
|
+
// 9. Length limit
|
|
159
|
+
const truncated = text.length > MAX_LENGTH;
|
|
160
|
+
if (truncated) {
|
|
161
|
+
text = text.slice(0, MAX_LENGTH);
|
|
162
|
+
warnings.push('length_truncated');
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
sanitized: text,
|
|
166
|
+
warnings,
|
|
167
|
+
originalLength,
|
|
168
|
+
truncated,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Quote for embedding
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
export function quoteForEmbedding(input, label) {
|
|
175
|
+
const result = sanitizeForPromptEmbedding(input);
|
|
176
|
+
const effectiveLabel = label ?? 'User Input';
|
|
177
|
+
const lines = [];
|
|
178
|
+
if (result.warnings.length > 0) {
|
|
179
|
+
lines.push(`> WARNING: Content was sanitized (${result.warnings.length} issues detected)`);
|
|
180
|
+
}
|
|
181
|
+
lines.push(`> **[${effectiveLabel}]**`);
|
|
182
|
+
for (const line of result.sanitized.split('\n')) {
|
|
183
|
+
lines.push(`> ${line}`);
|
|
184
|
+
}
|
|
185
|
+
return lines.join('\n');
|
|
186
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counting semaphore for limiting concurrent access to a shared resource.
|
|
3
|
+
*
|
|
4
|
+
* Used by the orchestrator to cap the number of parallel CLI invocations
|
|
5
|
+
* so that system resources (CPU, file handles, network) are not exhausted.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Semaphore {
|
|
8
|
+
private readonly maxConcurrency;
|
|
9
|
+
private _activeCount;
|
|
10
|
+
private _waitQueue;
|
|
11
|
+
constructor(maxConcurrency: number);
|
|
12
|
+
/** Acquire a slot. Resolves immediately when a slot is available, otherwise waits. */
|
|
13
|
+
acquire(): Promise<void>;
|
|
14
|
+
/** Release a slot. Wakes the next waiter if any. */
|
|
15
|
+
release(): void;
|
|
16
|
+
/** Run a function with automatic acquire/release. */
|
|
17
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
18
|
+
/** Number of currently active tasks. */
|
|
19
|
+
get activeCount(): number;
|
|
20
|
+
/** Number of tasks waiting for a slot. */
|
|
21
|
+
get waitingCount(): number;
|
|
22
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counting semaphore for limiting concurrent access to a shared resource.
|
|
3
|
+
*
|
|
4
|
+
* Used by the orchestrator to cap the number of parallel CLI invocations
|
|
5
|
+
* so that system resources (CPU, file handles, network) are not exhausted.
|
|
6
|
+
*/
|
|
7
|
+
export class Semaphore {
|
|
8
|
+
maxConcurrency;
|
|
9
|
+
_activeCount = 0;
|
|
10
|
+
_waitQueue = [];
|
|
11
|
+
constructor(maxConcurrency) {
|
|
12
|
+
this.maxConcurrency = maxConcurrency;
|
|
13
|
+
if (maxConcurrency < 1 || !Number.isInteger(maxConcurrency)) {
|
|
14
|
+
throw new Error(`Semaphore maxConcurrency must be a positive integer, got: ${maxConcurrency}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Acquire a slot. Resolves immediately when a slot is available, otherwise waits. */
|
|
18
|
+
async acquire() {
|
|
19
|
+
if (this._activeCount < this.maxConcurrency) {
|
|
20
|
+
this._activeCount++;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
this._waitQueue.push(resolve);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Release a slot. Wakes the next waiter if any. */
|
|
28
|
+
release() {
|
|
29
|
+
if (this._waitQueue.length > 0) {
|
|
30
|
+
// Hand the slot directly to the next waiter without decrementing.
|
|
31
|
+
const next = this._waitQueue.shift();
|
|
32
|
+
// _activeCount stays the same — ownership transfers to the waiter.
|
|
33
|
+
next();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this._activeCount--;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Run a function with automatic acquire/release. */
|
|
40
|
+
async run(fn) {
|
|
41
|
+
await this.acquire();
|
|
42
|
+
try {
|
|
43
|
+
return await fn();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
this.release();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Number of currently active tasks. */
|
|
50
|
+
get activeCount() {
|
|
51
|
+
return this._activeCount;
|
|
52
|
+
}
|
|
53
|
+
/** Number of tasks waiting for a slot. */
|
|
54
|
+
get waitingCount() {
|
|
55
|
+
return this._waitQueue.length;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process';
|
|
2
|
+
export declare function registerProcess(proc: ChildProcess): void;
|
|
3
|
+
/** Register a cleanup callback to run on SIGINT/SIGTERM (e.g., TUI terminal restore).
|
|
4
|
+
* Returns a deregistration function to prevent memory leaks in long-running sessions. */
|
|
5
|
+
export declare function registerCleanup(fn: () => void): () => void;
|
|
6
|
+
export declare function setupGracefulShutdown(): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const activeProcesses = new Set();
|
|
2
|
+
const cleanupCallbacks = [];
|
|
3
|
+
export function registerProcess(proc) {
|
|
4
|
+
activeProcesses.add(proc);
|
|
5
|
+
proc.on('close', () => activeProcesses.delete(proc));
|
|
6
|
+
proc.on('error', () => activeProcesses.delete(proc));
|
|
7
|
+
}
|
|
8
|
+
/** Register a cleanup callback to run on SIGINT/SIGTERM (e.g., TUI terminal restore).
|
|
9
|
+
* Returns a deregistration function to prevent memory leaks in long-running sessions. */
|
|
10
|
+
export function registerCleanup(fn) {
|
|
11
|
+
cleanupCallbacks.push(fn);
|
|
12
|
+
return () => {
|
|
13
|
+
const idx = cleanupCallbacks.indexOf(fn);
|
|
14
|
+
if (idx !== -1)
|
|
15
|
+
cleanupCallbacks.splice(idx, 1);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
let installed = false;
|
|
19
|
+
export function setupGracefulShutdown() {
|
|
20
|
+
if (installed)
|
|
21
|
+
return;
|
|
22
|
+
installed = true;
|
|
23
|
+
const handler = () => {
|
|
24
|
+
// Snapshot to avoid splice-during-iteration when callbacks deregister themselves
|
|
25
|
+
const callbacks = [...cleanupCallbacks];
|
|
26
|
+
for (const cb of callbacks) {
|
|
27
|
+
try {
|
|
28
|
+
cb();
|
|
29
|
+
}
|
|
30
|
+
catch { /* intentional: cleanup callbacks must not throw during shutdown */ }
|
|
31
|
+
}
|
|
32
|
+
for (const proc of activeProcesses) {
|
|
33
|
+
proc.kill('SIGTERM');
|
|
34
|
+
}
|
|
35
|
+
// If no active child processes, exit after one tick to allow pending I/O to flush
|
|
36
|
+
if (activeProcesses.size === 0) {
|
|
37
|
+
setImmediate(() => process.exit(0));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Grace period then force kill
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
for (const proc of activeProcesses) {
|
|
43
|
+
if (!proc.killed)
|
|
44
|
+
proc.kill('SIGKILL');
|
|
45
|
+
}
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}, 5_000).unref();
|
|
48
|
+
};
|
|
49
|
+
process.on('SIGINT', handler);
|
|
50
|
+
process.on('SIGTERM', handler);
|
|
51
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "magi-ai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MAGI System - Multi-AI CLI Deliberation Framework (Evangelion-inspired, unofficial fan-made)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
|
+
"default": "./dist/src/index.js"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"magi": "./dist/bin/magi.js",
|
|
18
|
+
"magi-mcp": "./dist/bin/magi-mcp.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/",
|
|
22
|
+
"!dist/test/",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:e2e": "MAGI_E2E=1 vitest run test/e2e",
|
|
31
|
+
"lint": "eslint src/",
|
|
32
|
+
"prebuild": "rm -r dist 2>/dev/null || true",
|
|
33
|
+
"build": "tsc && chmod +x dist/bin/magi.js dist/bin/magi-mcp.js",
|
|
34
|
+
"start": "npx tsx bin/magi.ts",
|
|
35
|
+
"benchmark": "npx tsx bin/magi-benchmark.ts",
|
|
36
|
+
"coverage": "vitest run --coverage",
|
|
37
|
+
"prepublishOnly": "npm run build && npm test"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/ryu-tada/MAGI-system.git"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"ai",
|
|
45
|
+
"multi-agent",
|
|
46
|
+
"consensus",
|
|
47
|
+
"deliberation",
|
|
48
|
+
"cli",
|
|
49
|
+
"claude",
|
|
50
|
+
"codex",
|
|
51
|
+
"gemini",
|
|
52
|
+
"mcp",
|
|
53
|
+
"code-review",
|
|
54
|
+
"evangelion",
|
|
55
|
+
"tui",
|
|
56
|
+
"terminal-ui",
|
|
57
|
+
"multi-model",
|
|
58
|
+
"nerv",
|
|
59
|
+
"model-context-protocol",
|
|
60
|
+
"ai-orchestration"
|
|
61
|
+
],
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
64
|
+
"chalk": "^5.4.0",
|
|
65
|
+
"commander": "^13.0.0",
|
|
66
|
+
"zod": "^3.24.0"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@eslint/js": "^10.0.1",
|
|
70
|
+
"@types/node": "^22.0.0",
|
|
71
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
72
|
+
"eslint": "^10.0.2",
|
|
73
|
+
"tsx": "^4.19.0",
|
|
74
|
+
"typescript": "^5.7.0",
|
|
75
|
+
"typescript-eslint": "^8.56.1",
|
|
76
|
+
"vitest": "^3.0.0"
|
|
77
|
+
},
|
|
78
|
+
"engines": {
|
|
79
|
+
"node": ">=20.0.0"
|
|
80
|
+
},
|
|
81
|
+
"license": "MIT"
|
|
82
|
+
}
|