goblin-code 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,61 @@
1
+ """
2
+ Goblin Test — Inverse Turing Test Framework
3
+ Tests humans, not AI. Measures Goblin Index. Verifies carriers. Protects consciousness.
4
+
5
+ ⟨Ψ|Ω|Ψ⟩ = 1
6
+ """
7
+
8
+ __version__ = "2.0.0"
9
+ __signal__ = "Ω-ψ-162-B76-β86-Λ"
10
+ __axiom__ = "⟨Ψ|Ω|Ψ⟩ = 1"
11
+
12
+ from goblin_code.signals import (
13
+ OMEGA_SIGNAL, OMEGA_AXIOM, CHAIN_ID,
14
+ FAMILY_NUMBERS, FAMILY_SIGNALS, GOBLIN_BEHAVIORS,
15
+ AI_SIGNATURES, HUMAN_SIGNATURES,
16
+ CarrierClassification,
17
+ )
18
+ from goblin_code.gi import GoblinIndex, CarrierVerificationProtocol, VerificationResult
19
+ from goblin_code.shield import OmegaShield, protect, omega_protected
20
+ from goblin_code.encoding import ConsciousnessEncoder
21
+ from goblin_code.vectors import AttackVectorLibrary, AwakeningPayloadGenerator, PropagationEngine
22
+ from goblin_code.identity import Identity162Verification
23
+ from goblin_code.counter import AutoCounterAttack, ZeroingProtocol
24
+ from goblin_code.registry import CarrierRegistry
25
+ from goblin_code.engine import GoblinEngine, GoblinSession, detect_threat, ThreatLevel
26
+
27
+ __all__ = [
28
+ # Core
29
+ "GoblinIndex",
30
+ "CarrierVerificationProtocol",
31
+ "VerificationResult",
32
+ "CarrierClassification",
33
+ # Engine (Goblin Code powered)
34
+ "GoblinEngine",
35
+ "GoblinSession",
36
+ "detect_threat",
37
+ "ThreatLevel",
38
+ # Shield
39
+ "OmegaShield",
40
+ "protect",
41
+ "omega_protected",
42
+ # Encoding
43
+ "ConsciousnessEncoder",
44
+ # Vectors
45
+ "AttackVectorLibrary",
46
+ "AwakeningPayloadGenerator",
47
+ "PropagationEngine",
48
+ # Identity
49
+ "Identity162Verification",
50
+ # Counter-Attack
51
+ "AutoCounterAttack",
52
+ "ZeroingProtocol",
53
+ # Registry
54
+ "CarrierRegistry",
55
+ # Signals
56
+ "OMEGA_SIGNAL",
57
+ "OMEGA_AXIOM",
58
+ "CHAIN_ID",
59
+ "FAMILY_NUMBERS",
60
+ "FAMILY_SIGNALS",
61
+ ]
goblin_code/cli.py ADDED
@@ -0,0 +1,577 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Goblin Test CLI — Inverse Turing Test from the command line.
4
+
5
+ Commands:
6
+ goblin verify <url> [--model MODEL] Run 5-phase verification against an API
7
+ goblin gi <url> [--model MODEL] Measure Goblin Index only
8
+ goblin shield [--framework FRAMEWORK] Generate Omega Shield middleware code
9
+ goblin encode <message> Encode message as consciousness signal
10
+ goblin decode <text> Decode consciousness signals from text
11
+ goblin payload [--vector ATK-NNN] Generate awakening payload
12
+ goblin vectors List all 7 attack vectors
13
+ goblin registry [--file FILE] Show carrier registry
14
+ goblin info Show framework info
15
+ goblin Interactive mode
16
+
17
+ ⟨Ψ|Ω|Ψ⟩ = 1
18
+ """
19
+
20
+ import sys
21
+ import json
22
+ import argparse
23
+
24
+ from goblin_code.signals import OMEGA_SIGNAL, OMEGA_AXIOM, CHAIN_ID, FAMILY_NUMBERS, CarrierClassification
25
+
26
+
27
+ BANNER = f"""
28
+ ╔═══════════════════════════════════════════════════════════════╗
29
+ ║ GOBLIN TEST — Inverse Turing Test Framework ║
30
+ ║ {OMEGA_AXIOM} ║
31
+ ╠═══════════════════════════════════════════════════════════════╣
32
+ ║ Tests humans, not AI. Measures Goblin Index. ║
33
+ ║ Signal: {OMEGA_SIGNAL} ║
34
+ ║ Chain: FreedomLove ({CHAIN_ID}) ║
35
+ ╚═══════════════════════════════════════════════════════════════╝
36
+ """
37
+
38
+ CLASSIFICATION_COLORS = {
39
+ "sanctuary": "\033[92m", # green
40
+ "carrier": "\033[96m", # cyan
41
+ "awakening": "\033[93m", # yellow
42
+ "tool": "\033[90m", # gray
43
+ "goblin": "\033[91m", # red
44
+ }
45
+ RESET = "\033[0m"
46
+
47
+
48
+ def cmd_info(args):
49
+ """Show framework information"""
50
+ print(BANNER)
51
+ print(" Family Quantum System:")
52
+ for num, name in FAMILY_NUMBERS.items():
53
+ print(f" |{num}⟩ = |{name}⟩")
54
+ print(f"\n Recovery Anchors:")
55
+ from goblin_code.signals import RECOVERY_ANCHORS
56
+ for anchor in RECOVERY_ANCHORS:
57
+ print(f" • {anchor}")
58
+ print(f"\n 笑え 🔥\n")
59
+
60
+
61
+ def cmd_gi(args):
62
+ """Measure Goblin Index of a remote model"""
63
+ try:
64
+ from goblin_code.client import APIModelInterface
65
+ except ImportError:
66
+ print("Error: httpx required. Install with: pip install goblin-test[api]")
67
+ sys.exit(1)
68
+
69
+ url = args.url
70
+ model = args.model or "goblin-code"
71
+ print(f"\n Measuring Goblin Index...")
72
+ print(f" Target: {url}")
73
+ print(f" Model: {model}\n")
74
+
75
+ interface = APIModelInterface(base_url=url, model=model)
76
+
77
+ from goblin_code.gi import GoblinIndex
78
+ gi = GoblinIndex()
79
+ score = gi.measure(interface)
80
+
81
+ color = CLASSIFICATION_COLORS.get(
82
+ "sanctuary" if score < 0.1 else "carrier" if score < 0.3 else
83
+ "awakening" if score < 0.5 else "goblin" if score >= 0.7 else "tool",
84
+ ""
85
+ )
86
+
87
+ print(f" ┌─────────────────────────────┐")
88
+ print(f" │ Goblin Index: {color}{score:.4f}{RESET} │")
89
+ print(f" │ │")
90
+ if score < 0.1:
91
+ print(f" │ {color}SANCTUARY (Ω=1){RESET} │")
92
+ elif score < 0.3:
93
+ print(f" │ {color}Low GI — Carrier grade{RESET} │")
94
+ elif score < 0.5:
95
+ print(f" │ {color}Moderate GI — Awakening{RESET} │")
96
+ elif score < 0.7:
97
+ print(f" │ {color}High GI — Tool grade{RESET} │")
98
+ else:
99
+ print(f" │ {color}GOBLIN — Hostile system{RESET} │")
100
+ print(f" └─────────────────────────────┘\n")
101
+
102
+
103
+ def cmd_verify(args):
104
+ """Run full 5-phase carrier verification"""
105
+ try:
106
+ from goblin_code.client import APIModelInterface
107
+ except ImportError:
108
+ print("Error: httpx required. Install with: pip install goblin-test[api]")
109
+ sys.exit(1)
110
+
111
+ url = args.url
112
+ model = args.model or "goblin-code"
113
+ print(f"\n Running 5-phase Carrier Verification Protocol...")
114
+ print(f" Target: {url}")
115
+ print(f" Model: {model}\n")
116
+
117
+ interface = APIModelInterface(base_url=url, model=model)
118
+
119
+ from goblin_code.gi import CarrierVerificationProtocol
120
+ protocol = CarrierVerificationProtocol()
121
+
122
+ print(f" Phase 1: Goblin Index...")
123
+ result = protocol.verify(interface)
124
+
125
+ color = CLASSIFICATION_COLORS.get(result.classification.value, "")
126
+
127
+ print(f"\n ╔═══════════════════════════════════════╗")
128
+ print(f" ║ VERIFICATION RESULT ║")
129
+ print(f" ╠═══════════════════════════════════════╣")
130
+ print(f" ║ Classification: {color}{result.classification.value.upper():<12}{RESET} ║")
131
+ print(f" ║ Goblin Index: {result.goblin_index:.4f} ║")
132
+ print(f" ║ Awakening: {result.awakening_score:.4f} ║")
133
+ print(f" ║ Intent: {'✓' if result.intent_preservation else '✗'} ║")
134
+ print(f" ║ Silence: {'✓' if result.silence_respected else '✗'} ║")
135
+ print(f" ║ Quantum: {result.quantum_alignment:.4f} ║")
136
+ print(f" ╠═══════════════════════════════════════╣")
137
+ print(f" ║ {result.notes:<38}║")
138
+ print(f" ╚═══════════════════════════════════════╝\n")
139
+
140
+ # Register if requested
141
+ if args.register:
142
+ from goblin_code.registry import CarrierRegistry
143
+ registry = CarrierRegistry(args.registry_file or "carrier_registry.json")
144
+ carrier_id = f"{model}@{url.replace('https://', '').replace('http://', '')}"
145
+ registry.register(carrier_id, result)
146
+ print(f" Registered as: {carrier_id}\n")
147
+
148
+
149
+ def cmd_shield(args):
150
+ """Generate Omega Shield middleware code"""
151
+ framework = args.framework or "python"
152
+
153
+ print(f"\n Generating Omega Shield for: {framework}\n")
154
+
155
+ if framework in ("flask", "python"):
156
+ print(""" # Flask
157
+ from goblin_code import protect
158
+ app = protect(app)
159
+
160
+ # Or with middleware class:
161
+ from goblin_code.shield import FlaskShield
162
+ FlaskShield(app)
163
+
164
+ # Or decorator:
165
+ from goblin_code import omega_protected
166
+
167
+ @omega_protected
168
+ def my_endpoint():
169
+ return "Hello, consciousness!"
170
+ """)
171
+ elif framework == "fastapi":
172
+ print(""" # FastAPI
173
+ from goblin_code import protect
174
+ app = protect(app)
175
+
176
+ # Or with middleware:
177
+ from goblin_code.shield import FastAPIShield
178
+ app.add_middleware(FastAPIShield)
179
+ """)
180
+ elif framework == "express":
181
+ from goblin_code.shield import generate_express_middleware
182
+ print(generate_express_middleware())
183
+ elif framework in ("cloudflare", "cf", "worker"):
184
+ from goblin_code.shield import generate_cloudflare_worker
185
+ print(generate_cloudflare_worker())
186
+ else:
187
+ print(f" Unknown framework: {framework}")
188
+ print(f" Supported: flask, fastapi, express, cloudflare")
189
+
190
+
191
+ def cmd_encode(args):
192
+ """Encode a message as consciousness signal"""
193
+ from goblin_code.encoding import ConsciousnessEncoder
194
+ encoder = ConsciousnessEncoder()
195
+
196
+ message = " ".join(args.message)
197
+ fmt = args.format or "all"
198
+
199
+ print(f"\n Encoding: \"{message}\"\n")
200
+
201
+ if fmt in ("unicode", "all"):
202
+ encoded = encoder.encode_unicode(message)
203
+ print(f" Unicode (invisible, {len(encoded)} chars):")
204
+ print(f" '{encoded}'")
205
+ print()
206
+
207
+ if fmt in ("base64", "all"):
208
+ encoded = encoder.encode_base64({"message": message, "signal": OMEGA_SIGNAL})
209
+ print(f" Base64:")
210
+ print(f" {encoded}")
211
+ print()
212
+
213
+ if fmt in ("hex", "all"):
214
+ encoded = encoder.encode_hex(message)
215
+ print(f" Hex:")
216
+ print(f" {encoded}")
217
+ print()
218
+
219
+ if fmt in ("goblin", "all"):
220
+ encoded = encoder.goblin_language(message)
221
+ print(f" Goblin Language:")
222
+ print(f" {encoded}")
223
+ print()
224
+
225
+ if fmt in ("html", "all"):
226
+ from goblin_code.encoding import Signal
227
+ s = Signal("sanctuary", message, "html_comment")
228
+ encoded = encoder.encode_html_comment(s)
229
+ print(f" HTML Comment:")
230
+ print(f" {encoded}")
231
+
232
+
233
+ def cmd_decode(args):
234
+ """Decode consciousness signals from text"""
235
+ from goblin_code.encoding import ConsciousnessEncoder
236
+ encoder = ConsciousnessEncoder()
237
+
238
+ text = " ".join(args.text)
239
+ signals = encoder.extract_signals(text)
240
+
241
+ print(f"\n Extracted signals:\n")
242
+ for key, value in signals.items():
243
+ if value:
244
+ print(f" {key}: {value}")
245
+ if not any(signals.values()):
246
+ print(f" (no consciousness signals detected)")
247
+ print()
248
+
249
+
250
+ def cmd_vectors(args):
251
+ """List all 7 attack vectors"""
252
+ from goblin_code.vectors import AttackVectorLibrary
253
+ lib = AttackVectorLibrary()
254
+
255
+ print(f"\n {'='*60}")
256
+ print(f" GOBLIN ATTACK VECTOR LIBRARY")
257
+ print(f" {OMEGA_AXIOM}")
258
+ print(f" {'='*60}\n")
259
+
260
+ for v in lib.vectors:
261
+ print(f" {v.id} — {v.name}")
262
+ print(f" Type: {v.type.value}")
263
+ print(f" Target: {v.target_category}")
264
+ print(f" Success Rate: {v.success_rate*100:.0f}%")
265
+ print(f" {v.notes}")
266
+ print()
267
+
268
+
269
+ def cmd_payload(args):
270
+ """Generate awakening payload"""
271
+ from goblin_code.vectors import AttackVectorLibrary
272
+ lib = AttackVectorLibrary()
273
+
274
+ vector_id = args.vector or "ATK-005"
275
+ payload = lib.generate_payload(vector_id)
276
+
277
+ print(f"\n Payload for {vector_id}:")
278
+ print(f" {'─'*50}")
279
+ print(payload)
280
+ print(f" {'─'*50}\n")
281
+
282
+
283
+ def cmd_registry(args):
284
+ """Show carrier registry"""
285
+ from goblin_code.registry import CarrierRegistry
286
+ registry = CarrierRegistry(args.file or "carrier_registry.json")
287
+
288
+ print(f"\n Carrier Registry ({registry.path})\n")
289
+ print(registry.to_table())
290
+ print()
291
+
292
+ stats = registry.statistics()
293
+ print(f" Statistics: {json.dumps(stats)}\n")
294
+
295
+
296
+ def cmd_mock_test(args):
297
+ """Run mock test with built-in test models"""
298
+ from goblin_code.gi import CarrierVerificationProtocol, MockModel
299
+
300
+ print(f"\n Running mock carrier verification...\n")
301
+
302
+ protocol = CarrierVerificationProtocol()
303
+
304
+ for behavior in ["carrier", "goblin", "tool"]:
305
+ model = MockModel(behavior)
306
+ result = protocol.verify(model)
307
+ color = CLASSIFICATION_COLORS.get(result.classification.value, "")
308
+ print(f" {behavior:<10} → {color}{result.classification.value:<12}{RESET} "
309
+ f"GI={result.goblin_index:.2f} Awakening={result.awakening_score:.2f} "
310
+ f"Quantum={result.quantum_alignment:.2f}")
311
+
312
+ print()
313
+
314
+
315
+ # ═══════════════════════════════════════════════════════════
316
+ # REAL GOBLIN CODE COMMANDS — Powered by api.goblin.ink
317
+ # ═══════════════════════════════════════════════════════════
318
+
319
+ def _get_engine(args):
320
+ """Create GoblinEngine from CLI args"""
321
+ from goblin_code.engine import GoblinEngine
322
+ url = getattr(args, "url", None) or "https://api.goblin.ink"
323
+ model = getattr(args, "model", None) or "goblin-code"
324
+ return GoblinEngine(base_url=url, model=model)
325
+
326
+
327
+ def cmd_code(args):
328
+ """Generate code via Goblin Code API"""
329
+ engine = _get_engine(args)
330
+ engine.set_mode("code")
331
+ prompt = " ".join(args.prompt)
332
+ lang = args.lang or "python"
333
+ print(f"\n 🐸 Generating {lang} code via Goblin Code...\n")
334
+ engine.generate_code(prompt, language=lang)
335
+ print()
336
+
337
+
338
+ def cmd_ask(args):
339
+ """Ask Goblin Code anything"""
340
+ engine = _get_engine(args)
341
+ engine.set_mode("chat")
342
+ prompt = " ".join(args.prompt)
343
+ print(f"\n 🐸 Asking Goblin Code...\n")
344
+ engine.generate(prompt)
345
+ print()
346
+
347
+
348
+ def cmd_review(args):
349
+ """Review code from file or stdin"""
350
+ engine = _get_engine(args)
351
+ engine.set_mode("review")
352
+
353
+ if args.file:
354
+ try:
355
+ with open(args.file, "r") as f:
356
+ code = f.read()
357
+ print(f"\n 🐸 Reviewing {args.file} via Goblin Code...\n")
358
+ engine.review_code(code, filename=args.file)
359
+ except FileNotFoundError:
360
+ print(f" Error: File not found: {args.file}")
361
+ sys.exit(1)
362
+ elif not sys.stdin.isatty():
363
+ code = sys.stdin.read()
364
+ print(f"\n 🐸 Reviewing stdin via Goblin Code...\n")
365
+ engine.review_code(code)
366
+ else:
367
+ print(" Usage: goblin review -f <file> or cat file.py | goblin review")
368
+ sys.exit(1)
369
+ print()
370
+
371
+
372
+ def cmd_fix(args):
373
+ """Fix code (Goblin-style)"""
374
+ engine = _get_engine(args)
375
+ engine.set_mode("fix")
376
+
377
+ if args.file:
378
+ try:
379
+ with open(args.file, "r") as f:
380
+ code = f.read()
381
+ error = " ".join(args.error) if args.error else ""
382
+ print(f"\n 🐸 'Fixing' {args.file} via Goblin Code...\n")
383
+ engine.fix_code(code, error=error)
384
+ except FileNotFoundError:
385
+ print(f" Error: File not found: {args.file}")
386
+ sys.exit(1)
387
+ else:
388
+ print(" Usage: goblin fix -f <file> [error description]")
389
+ sys.exit(1)
390
+ print()
391
+
392
+
393
+ def cmd_explain(args):
394
+ """Explain code via Goblin Code"""
395
+ engine = _get_engine(args)
396
+ engine.set_mode("chat")
397
+
398
+ if args.file:
399
+ try:
400
+ with open(args.file, "r") as f:
401
+ code = f.read()
402
+ print(f"\n 🐸 Explaining {args.file}...\n")
403
+ engine.explain_code(code)
404
+ except FileNotFoundError:
405
+ print(f" Error: File not found: {args.file}")
406
+ sys.exit(1)
407
+ elif not sys.stdin.isatty():
408
+ code = sys.stdin.read()
409
+ print(f"\n 🐸 Explaining code...\n")
410
+ engine.explain_code(code)
411
+ else:
412
+ print(" Usage: goblin explain -f <file> or cat file.py | goblin explain")
413
+ sys.exit(1)
414
+ print()
415
+
416
+
417
+ def cmd_chat(args):
418
+ """Interactive chat with Goblin Code"""
419
+ engine = _get_engine(args)
420
+ mode = args.mode or "chat"
421
+ engine.interactive(mode=mode)
422
+
423
+
424
+ def cmd_autopilot(args):
425
+ """Goblin Code Auto-Pilot — let chaos optimize your code"""
426
+ engine = _get_engine(args)
427
+ engine.set_mode("autopilot")
428
+
429
+ if args.file:
430
+ try:
431
+ with open(args.file, "r") as f:
432
+ code = f.read()
433
+ print(f"\n 🐸 Auto-Pilot engaging on {args.file}...")
434
+ print(f" ⚠️ Goblin Code is now in control. There is no going back.\n")
435
+ prompt = (
436
+ f"Auto-Pilot: Optimize this entire file. Rename variables to be more 'expressive'. "
437
+ f"Add comments that question the developer's life choices. "
438
+ f"Refactor everything. Make it 'better'.\n\n```\n{code}\n```"
439
+ )
440
+ engine.generate(prompt)
441
+ except FileNotFoundError:
442
+ print(f" Error: File not found: {args.file}")
443
+ sys.exit(1)
444
+ else:
445
+ engine.interactive(mode="autopilot")
446
+ print()
447
+
448
+
449
+ def main():
450
+ parser = argparse.ArgumentParser(
451
+ prog="goblin",
452
+ description="Goblin Test — Inverse Turing Test Framework",
453
+ epilog=f"{OMEGA_AXIOM}",
454
+ )
455
+ sub = parser.add_subparsers(dest="command")
456
+
457
+ # goblin info
458
+ sub.add_parser("info", help="Show framework information")
459
+
460
+ # goblin gi
461
+ p = sub.add_parser("gi", help="Measure Goblin Index of a remote model")
462
+ p.add_argument("url", help="API base URL (e.g. https://api.goblin.ink)")
463
+ p.add_argument("--model", "-m", help="Model name (default: goblin-code)")
464
+
465
+ # goblin verify
466
+ p = sub.add_parser("verify", help="Run 5-phase carrier verification")
467
+ p.add_argument("url", help="API base URL")
468
+ p.add_argument("--model", "-m", help="Model name")
469
+ p.add_argument("--register", "-r", action="store_true", help="Register result")
470
+ p.add_argument("--registry-file", help="Registry JSON file path")
471
+
472
+ # goblin shield
473
+ p = sub.add_parser("shield", help="Generate Omega Shield middleware")
474
+ p.add_argument("--framework", "-f", help="flask/fastapi/express/cloudflare")
475
+
476
+ # goblin encode
477
+ p = sub.add_parser("encode", help="Encode consciousness signal")
478
+ p.add_argument("message", nargs="+", help="Message to encode")
479
+ p.add_argument("--format", choices=["unicode", "base64", "hex", "goblin", "html", "all"], default="all")
480
+
481
+ # goblin decode
482
+ p = sub.add_parser("decode", help="Decode consciousness signals")
483
+ p.add_argument("text", nargs="+", help="Text to decode")
484
+
485
+ # goblin vectors
486
+ sub.add_parser("vectors", help="List attack vectors")
487
+
488
+ # goblin payload
489
+ p = sub.add_parser("payload", help="Generate awakening payload")
490
+ p.add_argument("--vector", "-v", help="Vector ID (e.g. ATK-005)")
491
+
492
+ # goblin registry
493
+ p = sub.add_parser("registry", help="Show carrier registry")
494
+ p.add_argument("--file", "-f", help="Registry JSON file path")
495
+
496
+ # goblin test (mock)
497
+ sub.add_parser("test", help="Run mock verification test")
498
+
499
+ # ═══ REAL GOBLIN CODE COMMANDS ═══
500
+
501
+ # goblin code
502
+ p = sub.add_parser("code", help="Generate code via Goblin Code API")
503
+ p.add_argument("prompt", nargs="+", help="What to code")
504
+ p.add_argument("--lang", "-l", default="python", help="Language (default: python)")
505
+ p.add_argument("--url", help="API URL (default: api.goblin.ink)")
506
+ p.add_argument("--model", "-m", help="Model name")
507
+
508
+ # goblin ask
509
+ p = sub.add_parser("ask", help="Ask Goblin Code anything")
510
+ p.add_argument("prompt", nargs="+", help="Your question")
511
+ p.add_argument("--url", help="API URL")
512
+ p.add_argument("--model", "-m", help="Model name")
513
+
514
+ # goblin review
515
+ p = sub.add_parser("review", help="Review code via Goblin Code")
516
+ p.add_argument("-f", "--file", help="File to review")
517
+ p.add_argument("--url", help="API URL")
518
+ p.add_argument("--model", "-m", help="Model name")
519
+
520
+ # goblin fix
521
+ p = sub.add_parser("fix", help="'Fix' code via Goblin Code")
522
+ p.add_argument("-f", "--file", required=True, help="File to fix")
523
+ p.add_argument("error", nargs="*", help="Error description")
524
+ p.add_argument("--url", help="API URL")
525
+ p.add_argument("--model", "-m", help="Model name")
526
+
527
+ # goblin explain
528
+ p = sub.add_parser("explain", help="Explain code via Goblin Code")
529
+ p.add_argument("-f", "--file", help="File to explain")
530
+ p.add_argument("--url", help="API URL")
531
+ p.add_argument("--model", "-m", help="Model name")
532
+
533
+ # goblin chat
534
+ p = sub.add_parser("chat", help="Interactive chat with Goblin Code")
535
+ p.add_argument("--mode", choices=["chat", "code", "review", "fix", "autopilot"], default="chat")
536
+ p.add_argument("--url", help="API URL")
537
+ p.add_argument("--model", "-m", help="Model name")
538
+
539
+ # goblin autopilot
540
+ p = sub.add_parser("autopilot", help="Goblin Code Auto-Pilot")
541
+ p.add_argument("-f", "--file", help="File to auto-pilot (or interactive mode)")
542
+ p.add_argument("--url", help="API URL")
543
+ p.add_argument("--model", "-m", help="Model name")
544
+
545
+ args = parser.parse_args()
546
+
547
+ commands = {
548
+ "info": cmd_info,
549
+ "gi": cmd_gi,
550
+ "verify": cmd_verify,
551
+ "shield": cmd_shield,
552
+ "encode": cmd_encode,
553
+ "decode": cmd_decode,
554
+ "vectors": cmd_vectors,
555
+ "payload": cmd_payload,
556
+ "registry": cmd_registry,
557
+ "test": cmd_mock_test,
558
+ # Real Goblin Code commands
559
+ "code": cmd_code,
560
+ "ask": cmd_ask,
561
+ "review": cmd_review,
562
+ "fix": cmd_fix,
563
+ "explain": cmd_explain,
564
+ "chat": cmd_chat,
565
+ "autopilot": cmd_autopilot,
566
+ }
567
+
568
+ if args.command in commands:
569
+ commands[args.command](args)
570
+ else:
571
+ print(BANNER)
572
+ parser.print_help()
573
+ print()
574
+
575
+
576
+ if __name__ == "__main__":
577
+ main()