@aion0/forge 0.8.1 → 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.
Files changed (45) hide show
  1. package/RELEASE_NOTES.md +25 -6
  2. package/app/api/connectors/[id]/settings/route.ts +31 -37
  3. package/app/api/connectors/[id]/test/route.ts +260 -0
  4. package/app/api/connectors/install-local/route.ts +211 -0
  5. package/app/api/connectors/marketplace/route.ts +79 -0
  6. package/app/api/connectors/route.ts +41 -46
  7. package/app/api/jobs/route.ts +1 -0
  8. package/app/api/skills/install-local/route.ts +282 -0
  9. package/components/ConnectorsPanel.tsx +526 -211
  10. package/components/SettingsModal.tsx +1 -0
  11. package/components/SkillsPanel.tsx +42 -1
  12. package/lib/agents/claude-adapter.ts +4 -0
  13. package/lib/agents/types.ts +6 -0
  14. package/lib/chat/agent-loop.ts +13 -22
  15. package/lib/chat/protocols/http.ts +1 -1
  16. package/lib/chat/protocols/shell.ts +1 -1
  17. package/lib/chat/tool-dispatcher.ts +20 -20
  18. package/lib/connectors/migration.ts +110 -0
  19. package/lib/connectors/registry.ts +328 -0
  20. package/lib/connectors/sync.ts +305 -0
  21. package/lib/connectors/types.ts +253 -0
  22. package/lib/help-docs/00-overview.md +1 -0
  23. package/lib/help-docs/17-connectors.md +241 -189
  24. package/lib/help-docs/21-build-connector.md +314 -0
  25. package/lib/help-docs/CLAUDE.md +4 -2
  26. package/lib/init.ts +25 -0
  27. package/lib/jobs/dispatcher.ts +28 -8
  28. package/lib/jobs/scheduler.ts +21 -3
  29. package/lib/jobs/store.ts +11 -2
  30. package/lib/jobs/types.ts +12 -0
  31. package/lib/pipeline-scheduler.ts +3 -2
  32. package/lib/pipeline.ts +135 -13
  33. package/lib/plugins/registry.ts +9 -42
  34. package/lib/plugins/types.ts +4 -129
  35. package/lib/settings.ts +7 -0
  36. package/lib/skills.ts +27 -1
  37. package/lib/task-manager.ts +62 -2
  38. package/package.json +3 -1
  39. package/src/core/db/database.ts +4 -0
  40. package/lib/builtin-plugins/github-api.yaml +0 -93
  41. package/lib/builtin-plugins/gitlab.yaml +0 -860
  42. package/lib/builtin-plugins/mantis.probe.js +0 -176
  43. package/lib/builtin-plugins/mantis.yaml +0 -964
  44. package/lib/builtin-plugins/pmdb.yaml +0 -178
  45. package/lib/builtin-plugins/teams.yaml +0 -913
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Connector Types — independent of the plugin (pipeline-node) subsystem.
3
+ *
4
+ * Connectors expose tools to Forge chat and the browser extension.
5
+ * Manifests live in <dataDir>/connectors/<id>/manifest.yaml, fetched
6
+ * from the remote `forge-connectors` registry. There are no built-in
7
+ * connectors — first launch requires a successful registry sync (which
8
+ * is cached afterwards for offline use).
9
+ *
10
+ * See lib/help-docs/17-connectors.md for the user-facing manifest spec.
11
+ */
12
+
13
+ /** Where a connector's scripts run inside the extension. */
14
+ export type ConnectorRunner = 'main' | 'isolated';
15
+
16
+ /** Where a tool's execution lives. */
17
+ export type ConnectorProtocol = 'browser' | 'http' | 'shell';
18
+
19
+ /** Schema for one settings or parameter field. */
20
+ export interface ConnectorFieldSchema {
21
+ type: 'string' | 'number' | 'boolean' | 'secret' | 'json' | 'select';
22
+ label?: string;
23
+ description?: string;
24
+ required?: boolean;
25
+ default?: unknown;
26
+ /** select-type options */
27
+ options?: string[];
28
+ }
29
+
30
+ /**
31
+ * Server-side HTTP request shape, used by `protocol: http` tools.
32
+ * Template tokens {base_url}, {settings.*}, {args.*} are expanded at run time.
33
+ */
34
+ export interface HttpRequestSpec {
35
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
36
+ /** Full URL. Templated. */
37
+ url: string;
38
+ /** Header values are templated. */
39
+ headers?: Record<string, string>;
40
+ /** Query params. Values templated. Appended after any existing ? on url. */
41
+ query?: Record<string, string>;
42
+ /** Body. string = sent as-is (templated); object = JSON.stringify'd (string values templated). */
43
+ body?: string | Record<string, unknown>;
44
+ }
45
+
46
+ /**
47
+ * Where the extension's generic runner should land the active tab before
48
+ * executing a tool's script.
49
+ */
50
+ export interface ConnectorPage {
51
+ /** Template URL; supports {base_url}, {settings.*}, {args.*}. */
52
+ url: string;
53
+ /**
54
+ * Substring; if the current tab URL already contains it, skip
55
+ * navigation. Templated values are expanded the same way as `url`
56
+ * (settings server-side, args at runtime). Omit to always navigate.
57
+ */
58
+ on_target?: string;
59
+ }
60
+
61
+ /**
62
+ * A single callable a connector exposes to the LLM.
63
+ *
64
+ * For `protocol: 'browser'` the script body runs in the user's tab via
65
+ * chrome.scripting.executeScript (page context, has document/fetch/etc,
66
+ * no chrome.* APIs). The extension is a generic runner — it doesn't
67
+ * know about specific connectors. Adding a new connector means writing
68
+ * a manifest with `page` + `script` per tool; no extension rebuild.
69
+ */
70
+ export interface ConnectorTool {
71
+ description: string;
72
+ parameters?: Record<string, ConnectorFieldSchema>;
73
+ /** Requires user confirmation before invoking (e.g. add_comment, close_issue). */
74
+ destructive?: boolean;
75
+ /** Free-form description of the return shape — surfaced to the LLM. */
76
+ returns?: string;
77
+
78
+ /** Where this tool runs. Default 'browser'. */
79
+ protocol?: ConnectorProtocol;
80
+
81
+ // ── protocol: 'browser' ───────────────────────────────────
82
+ /** Page to navigate to before running the script. */
83
+ page?: ConnectorPage;
84
+ /**
85
+ * JavaScript function body. Receives `args` (the LLM's parsed
86
+ * parameters). Returns a JSON-serializable value. Runs in the user's
87
+ * tab — must be self-contained (no closures over Forge/extension code).
88
+ */
89
+ script?: string;
90
+
91
+ // ── protocol: 'http' ──────────────────────────────────────
92
+ /** Request shape. Templates {base_url}, {settings.*}, {args.*}. */
93
+ request?: HttpRequestSpec;
94
+
95
+ // ── protocol: 'shell' ─────────────────────────────────────
96
+ /** Command + args (each templated independently — no shell injection). */
97
+ command?: string[];
98
+ /** Working directory (templated). */
99
+ cwd?: string;
100
+ /** Extra env vars (values templated). */
101
+ env?: Record<string, string>;
102
+
103
+ /** shell/http: timeout in milliseconds. Default 30000, max 300000. */
104
+ timeout_ms?: number;
105
+ }
106
+
107
+ /**
108
+ * One adapter inside a connector. Most connectors are 1:1 (single tool
109
+ * set, single auth) — the manifest's top-level `tools`/`settings`/
110
+ * `host_match` fields define that single entry. Use `connectors[]`
111
+ * only when one auth covers multiple sibling adapters (Atlassian,
112
+ * Google Workspace, M365).
113
+ */
114
+ export interface ConnectorEntry {
115
+ id: string;
116
+ host_permissions?: string[];
117
+ tools: Record<string, ConnectorTool>;
118
+ /** Per-user settings (host URL, default project, etc.). */
119
+ settings?: Record<string, ConnectorFieldSchema>;
120
+ /**
121
+ * Chrome match pattern. Runner uses this to find/open authenticated
122
+ * tabs for this connector. Supports {base_url}, {settings.*}.
123
+ */
124
+ host_match?: string;
125
+ /**
126
+ * Substring. If the tab URL contains this after navigation, treat as
127
+ * "user not logged in" and abort with loginRequired: true.
128
+ */
129
+ login_redirect?: string;
130
+ /** Inherits from ConnectorDefinition.runner if unset. */
131
+ runner?: ConnectorRunner;
132
+ }
133
+
134
+ /**
135
+ * Optional reachability probe shipped inside a connector manifest.
136
+ * Used by the Settings → Connectors "Test" button — the UI hits
137
+ * `POST /api/connectors/<id>/test`, which dispatches to one of:
138
+ *
139
+ * probe: 'http' (default) — server issues a one-shot HTTP request
140
+ * with {settings.*} expanded. Use this
141
+ * when the service has a clean REST
142
+ * endpoint (`/api/v4/user`, `/rate_limit`).
143
+ *
144
+ * probe: 'browser' — forwarded to the browser extension via
145
+ * the bridge. Extension acquires/opens a
146
+ * tab matching `host_match`, navigates,
147
+ * and checks the resulting URL against
148
+ * `login_redirect`. Verifies the user is
149
+ * actually logged in (cookie-based auth)
150
+ * — no server-side credentials involved.
151
+ */
152
+ export interface ConnectorTest {
153
+ /** Human-readable hint shown next to the Test button. */
154
+ description?: string;
155
+
156
+ /**
157
+ * Probe kind. Default 'http'. Browser probes require an installed +
158
+ * paired Forge browser extension.
159
+ */
160
+ probe?: 'http' | 'browser';
161
+
162
+ // ── probe: 'http' ────────────────────────────────────────
163
+ /** HTTP request to issue. Same template tokens as a tool request. */
164
+ request?: HttpRequestSpec;
165
+ /**
166
+ * Status codes that count as success. Default [200].
167
+ * (Some APIs return 204 for a successful auth check.)
168
+ */
169
+ ok_status?: number[];
170
+ /**
171
+ * Template for the success message. Tokens `{{<json-path>}}` against
172
+ * the parsed response body. Empty → "OK (HTTP <status>)".
173
+ * Example: "Authenticated as {{username}} ({{name}})".
174
+ */
175
+ ok_template?: string;
176
+
177
+ // ── probe: 'browser' ─────────────────────────────────────
178
+ // No fields required — the extension reuses the connector's
179
+ // top-level host_match + login_redirect (1:1) or the first entry's
180
+ // (1:N) to find the tab and detect login redirects.
181
+
182
+ /** Override the default timeout (http: 15s, browser: 30s). */
183
+ timeout_ms?: number;
184
+ }
185
+
186
+ /**
187
+ * The on-disk manifest for a connector, loaded from
188
+ * `<dataDir>/connectors/<id>/manifest.yaml`.
189
+ */
190
+ export interface ConnectorDefinition {
191
+ id: string;
192
+ name: string;
193
+ version: string;
194
+ /** Emoji or short string for UI badges. */
195
+ icon?: string;
196
+ author?: string;
197
+ description?: string;
198
+
199
+ /**
200
+ * Minimum Forge version this manifest expects. The registry filter
201
+ * hides newer-than-supported manifests so users on older Forge
202
+ * versions don't try to install something that depends on newer APIs.
203
+ */
204
+ min_forge_version?: string;
205
+
206
+ /**
207
+ * Which extension execution context runs the connector's scripts.
208
+ * Default 'main' (permissive-CSP sites). Use 'isolated' for strict
209
+ * CSP sites (Teams, github.com). Per-connector, not per-tool — a
210
+ * host has one CSP profile.
211
+ */
212
+ runner?: ConnectorRunner;
213
+
214
+ // ─── 1:1 connector — top-level fields ──────────────────
215
+ /** Most connectors expose tools directly here. */
216
+ tools?: Record<string, ConnectorTool>;
217
+ settings?: Record<string, ConnectorFieldSchema>;
218
+ host_match?: string;
219
+ login_redirect?: string;
220
+
221
+ // ─── 1:N suite — list of sibling entries sharing auth ──
222
+ connectors?: ConnectorEntry[];
223
+
224
+ /** Optional reachability probe — wired to the Settings "Test" button. */
225
+ test?: ConnectorTest;
226
+ }
227
+
228
+ /**
229
+ * A reference to a connector definition without its tools/scripts —
230
+ * used by the marketplace listing so we don't pay the YAML parse cost
231
+ * for connectors the user hasn't installed.
232
+ */
233
+ export interface ConnectorMarketEntry {
234
+ id: string;
235
+ name: string;
236
+ version: string;
237
+ icon?: string;
238
+ description?: string;
239
+ author?: string;
240
+ /** present if locally installed */
241
+ installed_version?: string;
242
+ /** true when registry has a newer version than installed_version */
243
+ update_available?: boolean;
244
+ /** true when min_forge_version is satisfied */
245
+ compatible: boolean;
246
+ /**
247
+ * Where this entry originates:
248
+ * 'registry' — listed in the remote registry (may also be installed)
249
+ * 'local' — installed via /api/connectors/install-local, no
250
+ * registry counterpart (no Update path)
251
+ */
252
+ source: 'registry' | 'local';
253
+ }
@@ -16,6 +16,7 @@ Forge is a self-hosted Vibe Coding platform for Claude Code. It provides a brows
16
16
  | **Telegram Bot** | Mobile control — submit tasks, receive notifications |
17
17
  | **Remote Access** | One-click Cloudflare tunnel for remote browsing |
18
18
  | **GitHub Issue Auto-fix** | Scan issues, auto-fix, create PRs |
19
+ | **Connectors Marketplace** | Connectors are an independent subsystem with their own registry — fetched from `aiwatching/forge-connectors` (override via `connectorsRepoUrl`). No built-ins; users install only what they need. PAT-style secrets are encrypted at rest. |
19
20
  | **Memory** | Long-term chat memory. Configure `@aion0/temper` for semantic + graph search, or leave URL/key blank to use the built-in local SQLite store (same block/episode API, keyword search). |
20
21
  | **Web Chat (simplified)** | `/chat` — minimal in-browser chat UI for use without the extension. Sessions, SSE streaming, memory badge. Full connector UX still lives in the extension. |
21
22
  | **IDE Plugins** | First-party VSCode extension and IntelliJ plugin — drive workspaces, agents, terminals, pipelines and docs from inside the editor (see `13-ide-plugins.md`) |