@aion0/forge 0.8.0 → 0.8.2
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/RELEASE_NOTES.md +25 -101
- package/app/api/connectors/[id]/settings/route.ts +31 -37
- package/app/api/connectors/[id]/test/route.ts +260 -0
- package/app/api/connectors/install-local/route.ts +211 -0
- package/app/api/connectors/marketplace/route.ts +79 -0
- package/app/api/connectors/route.ts +41 -46
- package/app/api/jobs/route.ts +1 -0
- package/app/api/monitor/route.ts +26 -0
- package/app/api/skills/install-local/route.ts +282 -0
- package/components/ConnectorsPanel.tsx +526 -211
- package/components/MonitorPanel.tsx +43 -0
- package/components/SettingsModal.tsx +1 -0
- package/components/SkillsPanel.tsx +42 -1
- package/lib/agents/claude-adapter.ts +4 -0
- package/lib/agents/types.ts +6 -0
- package/lib/chat/agent-loop.ts +14 -23
- package/lib/chat/local-memory.ts +2 -2
- package/lib/chat/memory-store.ts +1 -1
- package/lib/chat/protocols/http.ts +2 -2
- package/lib/chat/protocols/shell.ts +2 -2
- package/lib/chat/session-store.ts +2 -2
- package/lib/chat/tool-dispatcher.ts +21 -21
- package/lib/connectors/migration.ts +110 -0
- package/lib/connectors/registry.ts +328 -0
- package/lib/connectors/sync.ts +305 -0
- package/lib/connectors/types.ts +253 -0
- package/lib/help-docs/00-overview.md +1 -0
- package/lib/help-docs/17-connectors.md +241 -189
- package/lib/help-docs/21-build-connector.md +314 -0
- package/lib/help-docs/CLAUDE.md +4 -2
- package/lib/init.ts +25 -0
- package/lib/jobs/dispatcher.ts +28 -8
- package/lib/jobs/scheduler.ts +21 -3
- package/lib/jobs/store.ts +11 -2
- package/lib/jobs/types.ts +12 -0
- package/lib/pipeline-scheduler.ts +3 -2
- package/lib/pipeline.ts +135 -13
- package/lib/plugins/registry.ts +9 -42
- package/lib/plugins/types.ts +4 -129
- package/lib/settings.ts +7 -0
- package/lib/skills.ts +27 -1
- package/lib/task-manager.ts +62 -2
- package/package.json +3 -1
- package/src/core/db/database.ts +4 -0
- package/lib/builtin-plugins/github-api.yaml +0 -93
- package/lib/builtin-plugins/gitlab.yaml +0 -860
- package/lib/builtin-plugins/mantis.probe.js +0 -176
- package/lib/builtin-plugins/mantis.yaml +0 -964
- package/lib/builtin-plugins/pmdb.yaml +0 -178
- package/lib/builtin-plugins/teams.yaml +0 -913
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
// Mantis selector probe — paste into DevTools Console on a Mantis page
|
|
2
|
-
// (my_view_page.php / view_all_bug_page.php) to discover stable
|
|
3
|
-
// selectors for THIS Mantis instance / theme.
|
|
4
|
-
//
|
|
5
|
-
// Handles both URL styles:
|
|
6
|
-
// - Mantis 1.x classic: /bug_view_page.php?bug_id=N (Forge, older self-hosted)
|
|
7
|
-
// - Mantis 2.x modern: /view.php?id=N
|
|
8
|
-
//
|
|
9
|
-
// Output:
|
|
10
|
-
// - Tables containing bug links, sorted by count
|
|
11
|
-
// - Per-table: first-row classes, cell breakdown, sample data
|
|
12
|
-
// - Suggested selectors block, paste-ready for the connector handler
|
|
13
|
-
//
|
|
14
|
-
// Re-run on each page the connector touches and after Mantis upgrades.
|
|
15
|
-
|
|
16
|
-
(async () => {
|
|
17
|
-
// Anchors that look like a bug-view link
|
|
18
|
-
const BUG_LINK_SELECTOR =
|
|
19
|
-
'a[href*="view.php?id="], a[href*="bug_view_page.php?bug_id="]';
|
|
20
|
-
// Extract numeric bug ID from a href
|
|
21
|
-
const BUG_ID_RE = /(?:[?&](?:bug_)?id=)(\d+)/;
|
|
22
|
-
// Row marker — checkbox carrying the bug id directly (old themes)
|
|
23
|
-
const ROW_CHECKBOX_SELECTOR = 'input[type="checkbox"][value][name*="bug"]';
|
|
24
|
-
|
|
25
|
-
const getBugId = (el) => {
|
|
26
|
-
if (!el) return null;
|
|
27
|
-
if (el.tagName === 'INPUT') return Number(el.value) || null;
|
|
28
|
-
const m = (el.href || '').match(BUG_ID_RE);
|
|
29
|
-
return m ? Number(m[1]) : null;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const describe = (el) => el.id ? `#${el.id}`
|
|
33
|
-
: el.className ? `${el.tagName.toLowerCase()}.${el.className.split(/\s+/).filter(Boolean).slice(0,2).join('.')}`
|
|
34
|
-
: el.tagName.toLowerCase();
|
|
35
|
-
const log = (k, v) => console.log(`%c${k}`, 'color:#06f;font-weight:bold', v);
|
|
36
|
-
const hr = () => console.log('━'.repeat(60));
|
|
37
|
-
|
|
38
|
-
console.group('🐞 Mantis selector probe');
|
|
39
|
-
log('Page', location.pathname);
|
|
40
|
-
|
|
41
|
-
const tables = [...document.querySelectorAll('table')].map((t, i) => {
|
|
42
|
-
const bugLinks = t.querySelectorAll(BUG_LINK_SELECTOR);
|
|
43
|
-
const checkboxes = t.querySelectorAll(ROW_CHECKBOX_SELECTOR);
|
|
44
|
-
return {
|
|
45
|
-
idx: i, el: t,
|
|
46
|
-
selector: describe(t),
|
|
47
|
-
rows: t.querySelectorAll('tr').length,
|
|
48
|
-
bugLinks: bugLinks.length,
|
|
49
|
-
bugCheckboxes: checkboxes.length,
|
|
50
|
-
nearestHeading: t.closest('section, div')?.querySelector('h1,h2,h3,h4,legend,.widget-title')?.innerText?.trim().slice(0,40) || ''
|
|
51
|
-
};
|
|
52
|
-
}).filter(t => t.bugLinks > 0 || t.bugCheckboxes > 0).sort((a,b) => (b.bugLinks + b.bugCheckboxes) - (a.bugLinks + a.bugCheckboxes));
|
|
53
|
-
|
|
54
|
-
if (!tables.length) {
|
|
55
|
-
console.warn('No bug-bearing table found. Either no bugs visible, or the markup uses a pattern this probe does not know about.');
|
|
56
|
-
console.log('Try the recon snippet at the bottom of this file (commented).');
|
|
57
|
-
console.groupEnd(); return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
log(`Tables with bug rows (${tables.length})`, '');
|
|
61
|
-
console.table(tables.map(({el, ...rest}) => rest));
|
|
62
|
-
hr();
|
|
63
|
-
|
|
64
|
-
tables.forEach((t, n) => {
|
|
65
|
-
console.groupCollapsed(`📋 Table #${n}: ${t.selector} (${t.bugLinks} links / ${t.bugCheckboxes} checkboxes, section: "${t.nearestHeading}")`);
|
|
66
|
-
// Bug row = any <tr> containing either a bug link or a bug checkbox
|
|
67
|
-
const bugRows = [...t.el.querySelectorAll('tr')].filter(r =>
|
|
68
|
-
r.querySelector(BUG_LINK_SELECTOR) || r.querySelector(ROW_CHECKBOX_SELECTOR)
|
|
69
|
-
);
|
|
70
|
-
log('Bug rows', bugRows.length);
|
|
71
|
-
if (!bugRows.length) { console.groupEnd(); return; }
|
|
72
|
-
|
|
73
|
-
const r1 = bugRows[0];
|
|
74
|
-
log('First row classes', r1.className || '(none)');
|
|
75
|
-
log('First row attrs (non-class)', Object.fromEntries(
|
|
76
|
-
[...r1.attributes].filter(a => a.name !== 'class').map(a => [a.name, a.value])
|
|
77
|
-
));
|
|
78
|
-
|
|
79
|
-
const cells = [...r1.querySelectorAll('td')];
|
|
80
|
-
console.table(cells.map((c, i) => ({
|
|
81
|
-
cell: i,
|
|
82
|
-
classes: c.className || '',
|
|
83
|
-
text: c.innerText.trim().slice(0, 45),
|
|
84
|
-
link: c.querySelector('a')?.href?.match(/(view\.php\?id=\d+|bug_view_page\.php\?bug_id=\d+|status_id=\d+|set_project[^&]+)/)?.[0] || '',
|
|
85
|
-
ckbox: c.querySelector(ROW_CHECKBOX_SELECTOR)?.value || ''
|
|
86
|
-
})));
|
|
87
|
-
|
|
88
|
-
const sample = bugRows.slice(0, 5).map(r => {
|
|
89
|
-
const link = r.querySelector(BUG_LINK_SELECTOR);
|
|
90
|
-
const checkbox = r.querySelector(ROW_CHECKBOX_SELECTOR);
|
|
91
|
-
const id = getBugId(link) || getBugId(checkbox);
|
|
92
|
-
return {
|
|
93
|
-
id,
|
|
94
|
-
summary: link?.title?.trim() || link?.textContent?.trim() || '',
|
|
95
|
-
statusText: [...r.querySelectorAll('td')].map(c => c.innerText.trim()).find(t => /open|closed|resolved|assigned|new|feedback|acknowledged|confirmed/i.test(t)) || '',
|
|
96
|
-
bgcolor: r.getAttribute('bgcolor') || '',
|
|
97
|
-
rowClass: r.className || '',
|
|
98
|
-
url: link?.href || ''
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
log('Sample (first 5 rows)', sample);
|
|
102
|
-
console.groupEnd();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
hr();
|
|
106
|
-
|
|
107
|
-
const best = tables[0];
|
|
108
|
-
// Pick the more reliable strategy
|
|
109
|
-
const useCheckbox = best.bugCheckboxes >= best.bugLinks;
|
|
110
|
-
const rowSelector = useCheckbox
|
|
111
|
-
? `${best.selector} tr:has(${ROW_CHECKBOX_SELECTOR})`
|
|
112
|
-
: `${best.selector} tr:has(${BUG_LINK_SELECTOR.split(', ')[0]}), ${best.selector} tr:has(${BUG_LINK_SELECTOR.split(', ')[1]})`;
|
|
113
|
-
|
|
114
|
-
console.log('%c✅ Suggested selectors for mantis.ts:', 'color:#0a0;font-weight:bold');
|
|
115
|
-
console.log(` bugTable: '${best.selector}'`);
|
|
116
|
-
console.log(` bugRow: '${rowSelector}'`);
|
|
117
|
-
console.log(` idSource: ${useCheckbox ? "row checkbox value (input[name*='bug'])" : 'href regex'}`);
|
|
118
|
-
console.log(` idAnchor: '${BUG_LINK_SELECTOR}'`);
|
|
119
|
-
console.log(` idRegex: ${BUG_ID_RE}`);
|
|
120
|
-
console.log(` rowCheckbox: '${ROW_CHECKBOX_SELECTOR}'`);
|
|
121
|
-
console.log(` status/severity: inspect "classes" + "text" columns above to identify which td holds them`);
|
|
122
|
-
console.groupEnd();
|
|
123
|
-
|
|
124
|
-
const out = {
|
|
125
|
-
page: location.pathname,
|
|
126
|
-
tableSelector: best.selector,
|
|
127
|
-
rowSelector,
|
|
128
|
-
idSource: useCheckbox ? 'checkbox' : 'href',
|
|
129
|
-
bugLinkSelector: BUG_LINK_SELECTOR,
|
|
130
|
-
bugIdRegex: BUG_ID_RE.source,
|
|
131
|
-
rowCheckboxSelector: ROW_CHECKBOX_SELECTOR,
|
|
132
|
-
sectionsFound: tables.length,
|
|
133
|
-
// Capture first-row cell layout so Claude can map column indices
|
|
134
|
-
firstRowCells: (() => {
|
|
135
|
-
const r1 = [...best.el.querySelectorAll('tr')].find(r =>
|
|
136
|
-
r.querySelector(BUG_LINK_SELECTOR) || r.querySelector(ROW_CHECKBOX_SELECTOR));
|
|
137
|
-
if (!r1) return [];
|
|
138
|
-
return [...r1.querySelectorAll('td')].map((c, i) => ({
|
|
139
|
-
cell: i,
|
|
140
|
-
classes: c.className || '',
|
|
141
|
-
text: c.innerText.trim().slice(0, 80),
|
|
142
|
-
}));
|
|
143
|
-
})(),
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// Auto-copy to clipboard — single Cmd+V to share
|
|
147
|
-
try {
|
|
148
|
-
await navigator.clipboard.writeText(JSON.stringify(out, null, 2));
|
|
149
|
-
console.log('%c📋 Copied to clipboard — paste to share', 'color:#0a0;font-weight:bold');
|
|
150
|
-
} catch (e) {
|
|
151
|
-
console.warn('Clipboard write failed (page may not have focus). Result still returned below.');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return out;
|
|
155
|
-
})();
|
|
156
|
-
|
|
157
|
-
// ----------------------------------------------------------------------
|
|
158
|
-
// Fallback recon — uncomment + paste if the main probe finds nothing
|
|
159
|
-
// ----------------------------------------------------------------------
|
|
160
|
-
// (() => {
|
|
161
|
-
// console.group('🔍 Page recon');
|
|
162
|
-
// console.log('URL:', location.href);
|
|
163
|
-
// console.log('Iframes:', document.querySelectorAll('iframe').length);
|
|
164
|
-
// console.log('Tables:', document.querySelectorAll('table').length);
|
|
165
|
-
// const anchors = [...document.querySelectorAll('a[href]')];
|
|
166
|
-
// console.log('Anchors with numeric-only text:', anchors.filter(a => /^\d{3,}$/.test(a.textContent.trim())).length);
|
|
167
|
-
// const patterns = new Set();
|
|
168
|
-
// anchors.forEach(a => {
|
|
169
|
-
// try {
|
|
170
|
-
// const u = new URL(a.href);
|
|
171
|
-
// patterns.add(u.pathname.replace(/\d+/g, 'N') + (u.search ? '?' + [...u.searchParams.keys()].sort().join('&') : ''));
|
|
172
|
-
// } catch {}
|
|
173
|
-
// });
|
|
174
|
-
// console.log('Unique href patterns:'); [...patterns].sort().forEach(p => console.log(' ', p));
|
|
175
|
-
// console.groupEnd();
|
|
176
|
-
// })();
|