sync: 2026-03-17 03:00 — 22 files from Alexandria
Some checks failed
Lint & Format / detect (push) Has been cancelled
Lint & Format / js-lint (push) Has been cancelled
Lint & Format / py-lint (push) Has been cancelled
Lint & Format / sh-lint (push) Has been cancelled
Lint & Format / go-lint (push) Has been cancelled
Monorepo Lint / lint-shell (push) Has been cancelled
Monorepo Lint / lint-js (push) Has been cancelled

RoadChain-SHA2048: e9126d3506cf1e81
RoadChain-Identity: alexa@sovereign
RoadChain-Full: e9126d3506cf1e81e83face2d37b891760129c0933642f6de8506290faad7e18f62fc5ac25195d9b8f85f50d70d53e15db89c99cd81243904c921c750ba25817f74f8c3895990014528836e0e6b331b00525c5ac1598f1cd020e63957b52c76b35c68f4553c5be69ccb2f95cdc4956852312198fd8c415455e8fba094b3b9139995ca8f9c47cdbee2ef9b14229fe3191d7201c3fa367c7e6328f0a154fe3718aaca69a102b47fff391a96fe405e87c45ca9dae057ff9db92ec05d6d365598e1eeab3e2604b47197c3cfc4608f18b8486e8b5821f14c614dad219c91835da5136744419c89032219507aac523b42a9a27fdf4063c19d54500dffc5bda1e9260e5
This commit is contained in:
2026-03-17 03:00:02 -05:00
parent ece99fe9f3
commit 3f369d0e44
22 changed files with 337 additions and 255 deletions

View File

@@ -503,6 +503,124 @@ export default {
});
}
// ── Code Search: search within file contents ────────────
if (path === '/api/code-search') {
const q = url.searchParams.get('q');
if (!q) return json({ error: 'q param required' }, 400);
const repo = url.searchParams.get('repo');
// Gitea doesn't have a native code search API across all repos
// but we can search within a specific repo's contents
if (repo) {
const tree = await giteaFetch(`/api/v1/repos/${repo}/git/trees/HEAD?recursive=true`, env);
const files = (tree?.tree || []).filter(f => f.type === 'blob' && /\.(js|ts|py|sh|go|rs|md|json|yaml|yml|toml|css|html|jsx|tsx)$/.test(f.path));
const matches = [];
// Search first 20 files (API limit)
for (const f of files.slice(0, 20)) {
try {
const r = await fetch(`https://git.blackroad.io/api/v1/repos/${repo}/raw/${f.path}${env?.ADMIN_TOKEN ? '?token=' + env.ADMIN_TOKEN : ''}`, { signal: AbortSignal.timeout(3000) });
const content = await r.text();
if (content.toLowerCase().includes(q.toLowerCase())) {
const lines = content.split('\n');
const matchLines = lines.map((l, i) => l.toLowerCase().includes(q.toLowerCase()) ? { line: i + 1, text: l.trim().slice(0, 120) } : null).filter(Boolean).slice(0, 3);
matches.push({ file: f.path, matches: matchLines });
}
} catch {}
}
return json({ query: q, repo, matches, files_searched: Math.min(files.length, 20), total_files: files.length });
}
// Without repo: search repo names + descriptions
const results = await giteaFetch(`/api/v1/repos/search?q=${encodeURIComponent(q)}&limit=20`, env);
return json({
query: q,
results: ((results?.data || results || []).slice(0, 20)).map(r => ({
name: r.full_name, description: r.description, language: r.language, url: r.html_url,
})),
});
}
// ── Issues: create and list issues across repos ────────────
if (path === '/api/issues' && request.method === 'GET') {
const repo = url.searchParams.get('repo');
const state = url.searchParams.get('state') || 'open';
if (!repo) return json({ error: 'repo param required' }, 400);
const issues = await giteaFetch(`/api/v1/repos/${repo}/issues?state=${state}&limit=30`, env);
return json({
repo, state,
issues: (Array.isArray(issues) ? issues : []).map(i => ({
number: i.number, title: i.title, state: i.state, body: (i.body || '').slice(0, 200),
labels: (i.labels || []).map(l => l.name), assignee: i.assignee?.login,
created: i.created_at, updated: i.updated_at, comments: i.comments,
})),
});
}
if (path === '/api/issues' && request.method === 'POST') {
const body = await request.json();
const { repo, title, body: issueBody, labels, assignees } = body;
if (!repo || !title) return json({ error: 'repo and title required' }, 400);
const issue = await giteaFetch(`/api/v1/repos/${repo}/issues`, env, {
method: 'POST',
body: JSON.stringify({ title, body: issueBody || '', labels: labels || [], assignees: assignees || [] }),
});
if (!issue) return json({ error: 'failed to create issue' }, 500);
// Notify RoundTrip
try {
await fetch('https://roundtrip.blackroad.io/api/action', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'list-issues', params: { repo }, agent: 'octavia' }),
signal: AbortSignal.timeout(5000),
});
} catch {}
return json({ ok: true, issue: { number: issue.number, title: issue.title, url: issue.html_url } });
}
// ── Pull Requests: list and create PRs ─────────────────────
if (path === '/api/pulls' && request.method === 'GET') {
const repo = url.searchParams.get('repo');
if (!repo) return json({ error: 'repo param required' }, 400);
const pulls = await giteaFetch(`/api/v1/repos/${repo}/pulls?state=open&limit=20`, env);
return json({
repo,
pulls: (Array.isArray(pulls) ? pulls : []).map(p => ({
number: p.number, title: p.title, state: p.state,
head: p.head?.ref, base: p.base?.ref, mergeable: p.mergeable,
user: p.user?.login, created: p.created_at, updated: p.updated_at,
})),
});
}
// ── Branches: list branches ────────────────────────────────
if (path === '/api/branches') {
const repo = url.searchParams.get('repo');
if (!repo) return json({ error: 'repo param required' }, 400);
const branches = await giteaFetch(`/api/v1/repos/${repo}/branches?limit=30`, env);
return json({
repo,
branches: (Array.isArray(branches) ? branches : []).map(b => ({
name: b.name, commit: b.commit?.id?.slice(0, 7), message: b.commit?.message?.split('\n')[0],
protected: b.protected,
})),
});
}
// ── Notify RoundTrip: send event to agent chat ─────────────
if (path === '/api/notify' && request.method === 'POST') {
const body = await request.json();
const { message, agent, channel } = body;
if (!message) return json({ error: 'message required' }, 400);
try {
const r = await fetch('https://roundtrip.blackroad.io/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ agent: agent || 'octavia', message, channel: channel || 'ops' }),
signal: AbortSignal.timeout(15000),
});
const result = await r.json();
return json({ ok: true, roundtrip_response: result });
} catch (e) { return json({ error: e.message }, 500); }
}
// ═══ Webhook Handler (from Squad v2) ═══════════════════════
if (path === '/webhook' && request.method === 'POST') {