1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#!/usr/bin/env python3
"""Build course/atlas.json from newOS4 source. Ground truth for every lesson claim."""
import json, os, re, glob, hashlib
from datetime import datetime, timezone
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OUT = os.path.join(ROOT, 'course', 'atlas.json')
CORE_DIR, EXT_DIR = os.path.join(ROOT, 'modules', 'core'), os.path.join(ROOT, 'modules', 'ext')
SKIP = {'core-bundle.js', 'critical-ext-bundle.js', 'sandbox-worker.js'}
CATEGORY = [
('module-fs', 'filesystem'), ('virtual-fs', 'filesystem'), ('module-aiassist', 'ai'), ('module-ollama', 'ai'),
('module-memory-graph', 'ai'), ('module-smartctx', 'ai'), ('module-neural-vfs', 'ai'), ('module-world-model', 'ai'),
('module-sandbox', 'ai'), ('module-searxng', 'web'), ('module-fetcher', 'web'), ('webdav', 'cloud'),
('editor', 'editor'), ('filemgr', 'filesystem'), ('finder', 'filesystem'), ('diff', 'editor'),
('cron', 'automation'), ('kanban', 'automation'), ('shell', 'shell'), ('busybox', 'shell'),
('theme', 'ui'), ('floating', 'ui'), ('voice', 'ui'), ('three', 'ui'), ('console', 'dev'), ('debug-panel', 'dev'),
('wpm', 'system'), ('tutorial', 'learning'), ('skill-pack-core', 'ai'), ('cryptogzip', 'system'),
('module-agent-registry', 'agents'), ('module-orchestrator', 'agents'), ('module-leases', 'agents'),
('module-chatstudio', 'ai'), ('module-servermon', 'system'), ('module-config', 'system'), ('module-system', 'system'),
('course', 'learning'),
]
def category_for(filename, cmd):
for frag, cat in CATEGORY:
if frag in filename: return cat
if cmd.startswith('webdav'): return 'cloud'
if cmd.startswith('cron') or cmd.startswith('kanban'): return 'automation'
if cmd.startswith('ai-') or cmd in ('ai', 'ask'): return 'ai'
return 'general'
def tier_lists():
rebuild = open(os.path.join(ROOT, 'scripts', 'rebuild-bundles.py')).read()
def listed(name):
m = re.search(name + r"\s*=\s*\[([^\]]+)\]", rebuild, re.S)
return set(re.findall(r"([a-z0-9-]+\.js)", m.group(1))) if m else set()
loader = open(os.path.join(ROOT, 'modules', 'core', 'module-loader.js')).read()
m = re.search(r'extKeys\s*=\s*\[([^\]]+)\]', loader)
ext = set(re.findall(r"'([a-z0-9-]+)'", m.group(1))) if m else set()
return listed('CORE_FILES'), listed('CRITICAL_EXT_FILES'), ext
CORE_FILES, CRITICAL_EXT_FILES, EXT_KEYS = tier_lists()
def module_tier(filename):
base = os.path.basename(filename)
if base in CRITICAL_EXT_FILES: return 'critical-ext-bundle'
if base in CORE_FILES: return 'core-bundle'
if base[:-3] in EXT_KEYS: return 'ext-auto'
return 'ext-manual'
def desc_map(text):
out = {}
for m in re.finditer(r"'([a-z0-9][a-z0-9_-]{1,40})'\s*:\s*'((?:[^'\\]|\\.){8,300})'", text):
cmd, desc = m.group(1), m.group(2)
if len(desc) < 10 or ' ' not in desc or desc.endswith('.js'):
continue
out.setdefault(cmd, desc.replace("\\'", "'"))
return out
def main():
commands, modules = {}, {}
files = sorted(glob.glob(os.path.join(CORE_DIR, '*.js')) + glob.glob(os.path.join(EXT_DIR, '*.js')))
for path in files:
base = os.path.basename(path)
if base in SKIP: continue
text = open(path, encoding='utf-8', errors='ignore').read()
cmds = sorted(set(re.findall(r"commands\['([A-Za-z0-9_-]+)'\]\s*=", text)))
if not cmds: continue
modname = base[:-3]
modules[modname] = {'file': os.path.relpath(path, ROOT), 'tier': module_tier(path),
'commands': cmds, 'lines': text.count('\n') + 1}
dm = desc_map(text)
for c in cmds:
commands[c] = {'module': modname, 'file': os.path.relpath(path, ROOT), 'tier': module_tier(path),
'category': category_for(base, c), 'desc': dm.get(c, ''),
'builtin': False, 'example': c}
term = open(os.path.join(ROOT, 'modules', 'core', 'terminal.js'), encoding='utf-8').read()
for c in sorted(set(re.findall(r"cmd === '([a-z0-9-]+)'", term))):
if c in commands: continue
commands[c] = {'module': 'terminal', 'file': 'modules/core/terminal.js', 'tier': 'core-bundle',
'category': 'system', 'desc': '', 'builtin': True, 'example': c}
idx_path = os.path.join(ROOT, 'modules-index.json')
mod_by_cmd = {}
if os.path.exists(idx_path):
idx = json.load(open(idx_path))
for m in idx.get('modules', {}).values():
for c in m.get('commands', []):
mod_by_cmd.setdefault(c, m)
for c, e in commands.items():
if not e['desc']:
m = mod_by_cmd.get(c) or {}
e['desc'] = (m.get('description') or f'{c} — command from {e["module"]}')[:300]
payload = {
'version': datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ'),
'source_hash': hashlib.sha256(''.join(sorted(commands)).encode()).hexdigest()[:16],
'commands': dict(sorted(commands.items())),
'modules': dict(sorted(modules.items())),
'coverage': {'commands': len(commands),
'described': sum(1 for e in commands.values() if e['desc']),
'modules': len(modules),
'tiers': {t: sum(1 for e in commands.values() if e['tier'] == t)
for t in ('core-bundle', 'critical-ext-bundle', 'ext-auto', 'ext-manual')}},
}
os.makedirs(os.path.dirname(OUT), exist_ok=True)
tmp = OUT + '.tmp'
with open(tmp, 'w', encoding='utf-8') as f:
json.dump(payload, f, ensure_ascii=False, indent=1)
os.replace(tmp, OUT)
os.chmod(OUT, 0o644)
print(json.dumps(payload['coverage'], ensure_ascii=False))
if __name__ == '__main__':
main()
|