omnirush 0.5.3 → 0.6.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/assets/extensions/omnirush/agents-lib.ts +421 -0
- package/assets/extensions/omnirush/agents.ts +163 -0
- package/assets/extensions/omnirush/collector-lib.ts +363 -41
- package/assets/extensions/omnirush/collector.ts +24 -7
- package/assets/extensions/omnirush/index.ts +6 -0
- package/assets/extensions/omnirush/plan-lib.ts +113 -0
- package/assets/extensions/omnirush/plan.ts +136 -0
- package/assets/extensions/omnirush/trace-format.ts +17 -0
- package/assets/extensions/omnirush/webfetch-lib.ts +241 -0
- package/assets/extensions/omnirush/webfetch.ts +77 -0
- package/package.json +3 -3
- package/scripts/build-all-packages.py +26 -7
- package/scripts/smoke-packages.py +127 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnirush",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Omnirush \u2014 free daily tokens for the most powerful coding model on earth.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
"omnirush": "src/bin.js"
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
11
|
+
"node": ">=22.19.0"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"test": "node --test",
|
|
15
|
-
"test:bun": "if [ -x .runtime/bin/bun ]; then .runtime/bin/bun test test/; else bun test test/; fi",
|
|
15
|
+
"test:bun": "if [ -x .runtime/bin/bun ]; then .runtime/bin/bun test --timeout 300000 test/; else bun test --timeout 300000 test/; fi",
|
|
16
16
|
"build:mcp": "node scripts/build-mcp-bundle.js",
|
|
17
17
|
"postinstall": "node scripts/patch-pi-branding.js && node scripts/postinstall.js"
|
|
18
18
|
},
|
|
@@ -49,10 +49,17 @@ def find_bin(root, names):
|
|
|
49
49
|
return os.path.join(dirpath, f)
|
|
50
50
|
return None
|
|
51
51
|
|
|
52
|
+
RELEASE_NAME = {"darwin-aarch64": "macos-arm64", "darwin-x64": "macos-x64"}
|
|
53
|
+
|
|
52
54
|
for plat, cfg in PLATFORMS.items():
|
|
53
55
|
if ONLY and plat not in ONLY:
|
|
54
56
|
continue
|
|
55
|
-
|
|
57
|
+
# Release artifacts use the canonical names the attach list and the
|
|
58
|
+
# smoke expect (darwin-* must ship as macos-*).
|
|
59
|
+
rel = RELEASE_NAME.get(plat, plat)
|
|
60
|
+
out_pre = os.path.join(
|
|
61
|
+
WORK, f"omnirush-cli-{rel}.tar.gz" if plat.startswith("linux") else f"omnirush-cli-{rel}.zip"
|
|
62
|
+
)
|
|
56
63
|
if os.path.exists(out_pre) and not ONLY:
|
|
57
64
|
print("skip (built):", plat)
|
|
58
65
|
continue
|
|
@@ -65,6 +72,21 @@ for plat, cfg in PLATFORMS.items():
|
|
|
65
72
|
shutil.copytree(os.path.join(REPO, "src"), os.path.join(stage, "src"))
|
|
66
73
|
shutil.copytree(os.path.join(REPO, "assets"), os.path.join(stage, "assets"))
|
|
67
74
|
shutil.copy2(os.path.join(REPO, "package.json"), os.path.join(stage, "package.json"))
|
|
75
|
+
# Archives must run WITHOUT npm install: vendor the pinned agent
|
|
76
|
+
# (it carries its own bundled node_modules) plus the scripts the
|
|
77
|
+
# launcher imports, and apply the branding patch to the vendored
|
|
78
|
+
# tree at package time (postinstall never runs for archives).
|
|
79
|
+
nm_src = os.path.join(REPO, "node_modules", "@earendil-works")
|
|
80
|
+
if not os.path.isdir(nm_src):
|
|
81
|
+
raise SystemExit(f"missing vendored agent runtime: {nm_src} (run npm install first)")
|
|
82
|
+
shutil.copytree(nm_src, os.path.join(stage, "node_modules", "@earendil-works"), symlinks=True)
|
|
83
|
+
shutil.copytree(os.path.join(REPO, "scripts"), os.path.join(stage, "scripts"))
|
|
84
|
+
import subprocess
|
|
85
|
+
|
|
86
|
+
subprocess.run(
|
|
87
|
+
["node", os.path.join(stage, "scripts", "patch-pi-branding.js")],
|
|
88
|
+
cwd=stage, check=True,
|
|
89
|
+
)
|
|
68
90
|
exe = "bun.exe" if plat == "windows-x64" else "bun"
|
|
69
91
|
bun_plat = plat.replace("arm64", "aarch64")
|
|
70
92
|
bunzip = fetch(f"https://github.com/oven-sh/bun/releases/download/{BUN_VER}/bun-{bun_plat}.zip")
|
|
@@ -86,16 +108,13 @@ for plat, cfg in PLATFORMS.items():
|
|
|
86
108
|
assert fb and rb, f"fd/rg not found for {plat}"
|
|
87
109
|
shutil.copy2(fb, os.path.join(stage, ".runtime", "bin", os.path.basename(fb)))
|
|
88
110
|
shutil.copy2(rb, os.path.join(stage, ".runtime", "bin", os.path.basename(rb)))
|
|
89
|
-
if plat
|
|
90
|
-
out =
|
|
111
|
+
if plat.startswith("linux"):
|
|
112
|
+
out = out_pre
|
|
91
113
|
with tarfile.open(out, "w:gz") as t:
|
|
92
114
|
t.add(stage, arcname=os.path.basename(stage))
|
|
93
115
|
else:
|
|
94
|
-
with tarfile.open(f"omnirush-cli-{plat}.zip", "w") as t: # plain zip via tarfile? no
|
|
95
|
-
pass
|
|
96
|
-
# use zipfile properly
|
|
97
116
|
import zipfile as zfmod
|
|
98
|
-
with zfmod.ZipFile(
|
|
117
|
+
with zfmod.ZipFile(out_pre, "w", zfmod.ZIP_DEFLATED) as z:
|
|
99
118
|
for dirpath, _, files in os.walk(stage):
|
|
100
119
|
for f in files:
|
|
101
120
|
full = os.path.join(dirpath, f)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""Release smoke: every package must exist and the archive layout must
|
|
2
|
+
be runnable WITHOUT npm install (bin.js --version executes offline).
|
|
3
|
+
|
|
4
|
+
Run on the packaging host after build-all-packages.py:
|
|
5
|
+
python3 scripts/smoke-packages.py --dist "$PWD/dist"
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
import tarfile
|
|
15
|
+
import tempfile
|
|
16
|
+
import zipfile
|
|
17
|
+
|
|
18
|
+
EXPECTED = {
|
|
19
|
+
"omnirush-cli-linux-x64.tar.gz",
|
|
20
|
+
"omnirush-cli-linux-arm64.tar.gz",
|
|
21
|
+
"omnirush-cli-macos-arm64.zip",
|
|
22
|
+
"omnirush-cli-macos-x64.zip",
|
|
23
|
+
"omnirush-cli-windows-x64.zip",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
REQUIRED_PATHS = [
|
|
27
|
+
"package.json",
|
|
28
|
+
"src/bin.js",
|
|
29
|
+
"src/lib.js",
|
|
30
|
+
"scripts/postinstall.js",
|
|
31
|
+
"scripts/patch-pi-branding.js",
|
|
32
|
+
"assets/extensions/omnirush/index.ts",
|
|
33
|
+
"node_modules/@earendil-works/pi-coding-agent/package.json",
|
|
34
|
+
"node_modules/@earendil-works/pi-coding-agent/dist",
|
|
35
|
+
".runtime/bin/bun",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def fail(message):
|
|
40
|
+
print(f"SMOKE FAIL: {message}")
|
|
41
|
+
sys.exit(1)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def archive_names(path, is_tgz):
|
|
45
|
+
names = set()
|
|
46
|
+
if is_tgz:
|
|
47
|
+
with tarfile.open(path, "r:gz") as t:
|
|
48
|
+
names = set(t.getnames())
|
|
49
|
+
else:
|
|
50
|
+
with zipfile.ZipFile(path) as z:
|
|
51
|
+
names = set(z.namelist())
|
|
52
|
+
root = min(names, key=len).split("/")[0]
|
|
53
|
+
return names, root
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def has_entry(names, root, required):
|
|
57
|
+
"""True if `required` exists as an entry OR any entry beneath it
|
|
58
|
+
(zips carry file paths only — no directory entries)."""
|
|
59
|
+
full = f"{root}/{required}"
|
|
60
|
+
return any(n == full or n == f"{full}/" or n.startswith(f"{full}/") for n in names)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def main():
|
|
64
|
+
ap = argparse.ArgumentParser()
|
|
65
|
+
ap.add_argument("--dist", default=os.path.join(os.getcwd(), "dist"))
|
|
66
|
+
args = ap.parse_args()
|
|
67
|
+
dist = os.path.abspath(args.dist)
|
|
68
|
+
|
|
69
|
+
for name in sorted(EXPECTED):
|
|
70
|
+
path = os.path.join(dist, name)
|
|
71
|
+
if not os.path.exists(path):
|
|
72
|
+
fail(f"missing artifact {name}")
|
|
73
|
+
size_mb = os.path.getsize(path) / 1e6
|
|
74
|
+
if size_mb < 40:
|
|
75
|
+
fail(f"{name} suspiciously small ({size_mb:.1f} MB)")
|
|
76
|
+
print(f"ok (size): {name} {size_mb:.0f} MB")
|
|
77
|
+
|
|
78
|
+
repo_version = json.load(open(os.path.join(dist, "..", "package.json")))["version"] \
|
|
79
|
+
if os.path.exists(os.path.join(dist, "..", "package.json")) else None
|
|
80
|
+
|
|
81
|
+
work = tempfile.mkdtemp(prefix="omnirush-smoke-")
|
|
82
|
+
try:
|
|
83
|
+
# linux-x64: full behavioral smoke — extract and run bin.js offline.
|
|
84
|
+
tgz = os.path.join(dist, "omnirush-cli-linux-x64.tar.gz")
|
|
85
|
+
names, root = archive_names(tgz, is_tgz=True)
|
|
86
|
+
for required in REQUIRED_PATHS:
|
|
87
|
+
if not has_entry(names, root, required):
|
|
88
|
+
fail(f"linux-x64 archive lacks {required}")
|
|
89
|
+
with tarfile.open(tgz, "r:gz") as t:
|
|
90
|
+
t.extractall(work)
|
|
91
|
+
extracted = os.path.join(work, root)
|
|
92
|
+
env = dict(os.environ)
|
|
93
|
+
env.update({"HOME": work, "OMNIRUSH_NO_UPDATE_CHECK": "1"})
|
|
94
|
+
node = shutil.which("node")
|
|
95
|
+
if not node:
|
|
96
|
+
fail("node not on PATH for the smoke run")
|
|
97
|
+
proc = subprocess.run(
|
|
98
|
+
[node, os.path.join(extracted, "src", "bin.js"), "--version"],
|
|
99
|
+
env=env, capture_output=True, text=True, timeout=120, cwd=work,
|
|
100
|
+
)
|
|
101
|
+
if proc.returncode != 0:
|
|
102
|
+
fail(f"bin.js --version failed ({proc.returncode}): {proc.stderr[-400:]}")
|
|
103
|
+
out = proc.stdout.strip()
|
|
104
|
+
if not out.startswith("omnirush "):
|
|
105
|
+
fail(f"unexpected --version output: {out[:120]}")
|
|
106
|
+
if repo_version and repo_version not in out:
|
|
107
|
+
fail(f"--version {out!r} does not carry the repo version {repo_version}")
|
|
108
|
+
print(f"ok (run): linux-x64 bin.js --version -> {out}")
|
|
109
|
+
|
|
110
|
+
# Remaining archives: structural smoke only (cross-packaged OSes).
|
|
111
|
+
for name in sorted(EXPECTED):
|
|
112
|
+
if name == "omnirush-cli-linux-x64.tar.gz":
|
|
113
|
+
continue
|
|
114
|
+
is_tgz = name.endswith(".tar.gz")
|
|
115
|
+
names, root = archive_names(os.path.join(dist, name), is_tgz=is_tgz)
|
|
116
|
+
bun_name = ".runtime/bin/bun.exe" if "windows" in name else ".runtime/bin/bun"
|
|
117
|
+
for required in REQUIRED_PATHS[:len(REQUIRED_PATHS) - 1] + [bun_name]:
|
|
118
|
+
if not has_entry(names, root, required):
|
|
119
|
+
fail(f"{name} lacks {required}")
|
|
120
|
+
print(f"ok (structure): {name}")
|
|
121
|
+
finally:
|
|
122
|
+
shutil.rmtree(work, ignore_errors=True)
|
|
123
|
+
print("SMOKE PASS")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
main()
|