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
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:
@@ -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') {
|
||||
|
||||
Reference in New Issue
Block a user