mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-10-01 22:14:51 +02:00
[eric] cleanup: convention fixes for merged #113/#107 (p-private rename, dead code, scratch files, em-dash, lint exceptions)
This commit is contained in:
@@ -33,7 +33,6 @@ p_refresh_task: Optional[asyncio.Task] = None
|
||||
|
||||
# The curated repo's recursive file tree, warmed hourly alongside the catalog. A curated install reads paths from here and fetches contents over raw, so it makes ZERO GitHub API calls in the normal case (the trees API is the 60/hr-limited part); update detection reads per-folder tree SHAs from it too. Empty until the first refresh warms it; install falls back to one live tree call then.
|
||||
p_curated_tree: list[dict] = []
|
||||
p_curated_tree_at: float = 0
|
||||
# Community repo trees for update detection, cached briefly (best-effort) so an updates check on skills.sh-installed skills doesn't refetch every page load nor burn the API.
|
||||
P_COMMUNITY_TREE_TTL = 600
|
||||
p_community_tree_cache: dict[str, tuple] = {}
|
||||
@@ -173,14 +172,13 @@ async def p_warm_curated_tree() -> None:
|
||||
over raw). One cheap call per hourly refresh, reused by every install in that hour.
|
||||
Isolated, a failure here never touches the SKILL.md catalog; install falls back to
|
||||
a live tree call while the cache is cold."""
|
||||
global p_curated_tree, p_curated_tree_at
|
||||
global p_curated_tree
|
||||
owner, _, repo = REPO.partition("/")
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0, headers=github_headers()) as client:
|
||||
tree = await p_tree_at(client, owner, repo, BRANCH)
|
||||
if tree:
|
||||
p_curated_tree = tree
|
||||
p_curated_tree_at = time.time()
|
||||
logger.info(f"Curated skill tree warmed: {len(p_tree_blob_paths(tree))} file paths cached")
|
||||
except RegistryRateLimited:
|
||||
# Visible on purpose: a rate-limited warm-up means installs stay on the slow live-call path until the IP's quota resets or a token is set.
|
||||
@@ -432,7 +430,7 @@ async def p_build_resolved_skill(
|
||||
if "SKILL.md" not in files:
|
||||
raise ValueError("SKILL.md could not be fetched")
|
||||
|
||||
meta, p_body = p_parse_frontmatter(files["SKILL.md"])
|
||||
meta, _ = p_parse_frontmatter(files["SKILL.md"])
|
||||
# Reuse the .swarm importer's content scan: flag files holding secret-shaped literals (the author's leaked key, or a sketchy skill) so the user sees it before installing from an unvetted repo.
|
||||
from backend.common.secret_scan import find_secrets_in_files
|
||||
secret_findings = find_secrets_in_files({rel: data.encode("utf-8", "ignore") for rel, data in files.items()})
|
||||
@@ -624,7 +622,7 @@ async def p_safe_repo_tree(source: str):
|
||||
if owner and repo:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0, headers=github_headers()) as client:
|
||||
p_branch, tree = await p_fetch_repo_tree(client, owner, repo)
|
||||
_, tree = await p_fetch_repo_tree(client, owner, repo)
|
||||
except Exception:
|
||||
tree = None
|
||||
p_community_tree_cache[source] = (now, tree)
|
||||
@@ -671,7 +669,7 @@ async def registry_update(req: p_UpdateRequest):
|
||||
bumping its version. Re-runs the secret scan and returns any findings so the UI can
|
||||
flag a community update that newly ships secrets. A skill with no source (user-made)
|
||||
can't be updated."""
|
||||
from backend.apps.skills.skills import sync_skills, write_folder_skill, p_clear_skill_dir
|
||||
from backend.apps.skills.skills import sync_skills, write_folder_skill, clear_skill_dir
|
||||
target = next((s for s in sync_skills() if s.id == req.skill_id), None)
|
||||
if target is None:
|
||||
raise HTTPException(status_code=404, detail="skill not found")
|
||||
@@ -690,7 +688,7 @@ async def registry_update(req: p_UpdateRequest):
|
||||
raise HTTPException(status_code=502, detail=f"could not fetch skill: {e}")
|
||||
|
||||
# Overwrite in place: clear first so files removed upstream don't linger, keep the user's command alias, refresh everything else from source.
|
||||
p_clear_skill_dir(target.id)
|
||||
clear_skill_dir(target.id)
|
||||
skill = write_folder_skill(
|
||||
target.id,
|
||||
resolved["files"],
|
||||
|
||||
@@ -361,7 +361,7 @@ async def get_skill(skill_id: str):
|
||||
raise HTTPException(status_code=404, detail="Skill not found")
|
||||
|
||||
|
||||
def p_clear_skill_dir(skill_id: str) -> None:
|
||||
def clear_skill_dir(skill_id: str) -> None:
|
||||
"""Empty a skill's folder before an in-place update so files removed upstream
|
||||
don't linger as orphans. write_folder_skill recreates the dir right after."""
|
||||
import shutil
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
// key-probe.js: inspect keyboard events INSIDE a game's guest webview.
|
||||
//
|
||||
// Why: the open question on the keyboard fix is whether tool-issued
|
||||
// sendInputEvent delivers correct key codes once the guest is focused, or
|
||||
// whether it arrives with an empty `code` / keyCode:0 (which games ignore) and
|
||||
// we must switch to CDP Input.dispatchKeyEvent. This probe answers it directly
|
||||
// instead of inferring from whether the sprite moved.
|
||||
//
|
||||
// Usage:
|
||||
// 1. Right-click the game webview -> Inspect -> Console (this is the GUEST
|
||||
// console, http://127.0.0.1:<port>/..., NOT the host app devtools).
|
||||
// 2. Paste this whole file and hit Enter. You'll see "[key-probe] armed".
|
||||
// 3. Fire one tool-issued press_key, e.g. { key: "ArrowRight", hold_ms: 800 }.
|
||||
// 4. Read the logged lines, or call __keyProbe.dump() for a table.
|
||||
//
|
||||
// What to look for per event:
|
||||
// - isTrusted: should be true (native OS-level event). false = a JS
|
||||
// dispatchEvent, not our native path.
|
||||
// - code: should be e.g. "ArrowRight". EMPTY string is the failure signal.
|
||||
// - keyCode/which: should be e.g. 39. 0 is the failure signal.
|
||||
// - holdMs (on keyup): wall-clock ms the key was held. ~0 means the hold
|
||||
// collapsed to an instant tap (down+up same tick); ~800 means hold worked.
|
||||
// Decision: clean code + nonzero keyCode -> stay on sendInputEvent. Empty
|
||||
// code / keyCode 0 -> move the keyboard path to CDP Input.dispatchKeyEvent.
|
||||
|
||||
(function () {
|
||||
if (window.__keyProbe) {
|
||||
try { window.__keyProbe.disarm(); } catch (_) {}
|
||||
}
|
||||
var events = [];
|
||||
var downAt = Object.create(null); // key -> timestamp, to measure hold duration
|
||||
|
||||
function row(e) {
|
||||
var now = (performance && performance.now) ? performance.now() : Date.now();
|
||||
var holdMs = null;
|
||||
if (e.type === 'keydown') {
|
||||
downAt[e.code || e.key] = now;
|
||||
} else if (e.type === 'keyup') {
|
||||
var k = e.code || e.key;
|
||||
if (downAt[k] != null) { holdMs = Math.round(now - downAt[k]); delete downAt[k]; }
|
||||
}
|
||||
var r = {
|
||||
type: e.type,
|
||||
key: e.key,
|
||||
code: e.code, // EMPTY = failure signal
|
||||
keyCode: e.keyCode, // 0 = failure signal
|
||||
which: e.which,
|
||||
isTrusted: e.isTrusted, // true = native; false = synthetic JS
|
||||
repeat: e.repeat,
|
||||
target: (e.target && (e.target.tagName || e.target.nodeName)) || '(none)',
|
||||
holdMs: holdMs, // only set on keyup
|
||||
};
|
||||
events.push(r);
|
||||
var warn = (r.code === '' || r.code == null) ? ' <-- EMPTY code'
|
||||
: (r.keyCode === 0) ? ' <-- keyCode 0' : '';
|
||||
console.log('[key-probe]', r.type, JSON.stringify(r) + warn);
|
||||
}
|
||||
|
||||
// Capture phase + on window so we see the event even if the game stops
|
||||
// propagation on its own listener.
|
||||
var types = ['keydown', 'keyup', 'keypress'];
|
||||
types.forEach(function (t) { window.addEventListener(t, row, true); });
|
||||
|
||||
window.__keyProbe = {
|
||||
events: events,
|
||||
dump: function () { try { console.table(events); } catch (_) { console.log(events); } return events; },
|
||||
clear: function () { events.length = 0; for (var k in downAt) delete downAt[k]; console.log('[key-probe] cleared'); },
|
||||
disarm: function () { types.forEach(function (t) { window.removeEventListener(t, row, true); }); console.log('[key-probe] disarmed'); },
|
||||
};
|
||||
|
||||
console.log('[key-probe] armed on', location.href, '- fire a press_key, then __keyProbe.dump(). document.activeElement =', document.activeElement && (document.activeElement.tagName || document.activeElement.nodeName));
|
||||
})();
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
# watch-moves.sh: human-readable, moves-only view of the App Agent.
|
||||
# Shows just the actions it takes (clicks, keypresses, waits), one per line,
|
||||
# plus task-start and bridge-missing milestones. Hides all the dispatch/result/
|
||||
# electron echo noise. Usage: bash backend/watch-moves.sh [logfile]
|
||||
LOG="${1:-/tmp/openswarm.log}"
|
||||
tail -f "$LOG" | awk '
|
||||
{ gsub(/\033\[[0-9;]*m/, "") } # strip color codes
|
||||
match($0, /[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/) { t = substr($0, RSTART, 8) }
|
||||
/\[app-agent\] START loop/ { print ""; print "=== " t " TASK START ==="; next }
|
||||
/BRIDGE MISSING/ { print t " !! bridge missing: app is NOT agent-operable, driving UI blind"; next }
|
||||
/\[browser-action\]/ {
|
||||
sub(/.*\[browser-action\] [A-Za-z]+: /, "") # drop everything up to the action
|
||||
sub(/ *-> .*/, "") # drop the trailing browser_id
|
||||
print t " > " $0
|
||||
next
|
||||
}
|
||||
'
|
||||
+1
-1
@@ -2444,7 +2444,7 @@ app.on('web-contents-created', (_event, contents) => {
|
||||
`).catch(() => {});
|
||||
|
||||
// Agent bridge (window.OPENSWARM_APP). Injected into EVERY app's main world
|
||||
// from the shell so it exists regardless of frontend/src — the lightweight
|
||||
// from the shell so it exists regardless of frontend/src; the lightweight
|
||||
// App Builder mode deletes frontend/src (and with it the template's own
|
||||
// agentBridge.ts), so this is the only entry point a trimmed app can't lose.
|
||||
// Idempotent + guarded: a workspace app that imports its own bridge installs
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
"backend/tests/test_disconnect_resilience.py",
|
||||
"backend/tests/test_outputs_runtime_cleanup.py",
|
||||
"backend/tests/test_service.py",
|
||||
"backend/tests/test_skill_registry_community.py",
|
||||
"backend/tests/test_streaming_harness.py",
|
||||
"backend/tests/test_swarm_bundle.py",
|
||||
"backend/tests/test_v2_invariants.py",
|
||||
@@ -197,6 +198,7 @@
|
||||
"p-private": [
|
||||
"backend/apps/workflows/workflows.py",
|
||||
"backend/tests/test_schedule_recurrence.py",
|
||||
"backend/tests/test_skill_registry_community.py",
|
||||
"backend/tests/test_ssrf_guard.py",
|
||||
"backend/tests/test_workflows_semantics.py",
|
||||
"backend/tests/test_workflows_storage.py"
|
||||
|
||||
Reference in New Issue
Block a user