@aion0/forge 0.10.17 → 0.10.18
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
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
# Forge v0.10.
|
|
1
|
+
# Forge v0.10.18
|
|
2
2
|
|
|
3
3
|
Released: 2026-05-30
|
|
4
4
|
|
|
5
|
-
## Changes since v0.10.
|
|
5
|
+
## Changes since v0.10.17
|
|
6
6
|
|
|
7
|
-
### Features
|
|
8
|
-
- feat: API profile model picker uses registry providers
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
**Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.16...v0.10.17
|
|
8
|
+
**Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.17...v0.10.18
|
|
@@ -398,9 +398,11 @@ const WebTerminal = forwardRef<WebTerminalHandle, WebTerminalProps>(function Web
|
|
|
398
398
|
agentSkipFlag = agentConfig?.skipPermissionsFlag || '';
|
|
399
399
|
} catch {}
|
|
400
400
|
|
|
401
|
-
// Resume flag: explicit sessionId > fixedSession > -c (only for session-capable agents)
|
|
401
|
+
// Resume flag: explicit sessionId > fixedSession > -c (only for session-capable agents).
|
|
402
|
+
// resumeMode === false means the user explicitly chose "New Session" — never inject
|
|
403
|
+
// a fixedSession then, or "new" silently resumes the current one.
|
|
402
404
|
let resumeFlag = '';
|
|
403
|
-
if (supportsSession) {
|
|
405
|
+
if (supportsSession && resumeMode !== false) {
|
|
404
406
|
if (sessionId) resumeFlag = ` --resume ${sessionId}`;
|
|
405
407
|
else if (resumeMode) resumeFlag = ' -c';
|
|
406
408
|
// Override with fixedSession if no explicit sessionId
|
|
@@ -987,9 +989,12 @@ const WebTerminal = forwardRef<WebTerminalHandle, WebTerminalProps>(function Web
|
|
|
987
989
|
currentSessionId,
|
|
988
990
|
});
|
|
989
991
|
} catch {
|
|
990
|
-
// Fallback: open directly without picker
|
|
992
|
+
// Fallback: open directly without picker.
|
|
993
|
+
// resumeMode:false so this fresh-open path skips the
|
|
994
|
+
// fixedSession resume branch downstream (else "open"
|
|
995
|
+
// silently resumes the current session).
|
|
991
996
|
window.dispatchEvent(new CustomEvent('forge:open-terminal', {
|
|
992
|
-
detail: { projectPath: p.path, projectName: p.name, agentId: a.id },
|
|
997
|
+
detail: { projectPath: p.path, projectName: p.name, agentId: a.id, resumeMode: false },
|
|
993
998
|
}));
|
|
994
999
|
}
|
|
995
1000
|
}}
|
|
@@ -1068,7 +1073,10 @@ const WebTerminal = forwardRef<WebTerminalHandle, WebTerminalProps>(function Web
|
|
|
1068
1073
|
onSelect={(sel) => {
|
|
1069
1074
|
const info = vibePickerInfo;
|
|
1070
1075
|
setVibePickerInfo(null);
|
|
1071
|
-
|
|
1076
|
+
// resumeMode must be LITERAL false for "new" — the downstream guard
|
|
1077
|
+
// is `resumeMode !== false`, so leaving it undefined lets fixedSession
|
|
1078
|
+
// get injected and "New session" silently resumes the current one.
|
|
1079
|
+
const detail: any = { projectPath: info.projectPath, projectName: info.projectName, agentId: info.agentId, profileEnv: info.profileEnv, resumeMode: false };
|
|
1072
1080
|
if (sel.mode !== 'new') { detail.resumeMode = true; detail.sessionId = sel.sessionId; }
|
|
1073
1081
|
window.dispatchEvent(new CustomEvent('forge:open-terminal', { detail }));
|
|
1074
1082
|
}}
|
package/lib/agents/index.ts
CHANGED
|
@@ -280,7 +280,12 @@ export function resolveTerminalLaunch(agentId?: string): TerminalLaunchInfo {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
return {
|
|
283
|
-
|
|
283
|
+
// Prefer the user-configured absolute binary path over the bare command
|
|
284
|
+
// name. A bare `claude` resolves via the tmux pane's PATH — non-login shell
|
|
285
|
+
// + forge-server's inherited PATH can pick a different/older install than
|
|
286
|
+
// the user's interactive shell, and an old claude crashes resuming a
|
|
287
|
+
// session a newer claude wrote. An absolute path bypasses PATH entirely.
|
|
288
|
+
cliCmd: agentCfg.path || cli.cmd,
|
|
284
289
|
cliType,
|
|
285
290
|
supportsSession: cli.session,
|
|
286
291
|
resumeFlag: agentCfg.resumeFlag || cli.resume,
|
|
@@ -189,6 +189,25 @@ const BUILTINS: Record<string, BuiltinHandler> = {
|
|
|
189
189
|
return line;
|
|
190
190
|
},
|
|
191
191
|
|
|
192
|
+
// Query a pipeline run's status + per-node results by id (pairs with
|
|
193
|
+
// trigger_pipeline's returned id). Mirrors the MCP get_pipeline_status tool.
|
|
194
|
+
get_pipeline_status: async (input) => {
|
|
195
|
+
const params = (input as { pipeline_id?: string } | undefined) || {};
|
|
196
|
+
if (!params.pipeline_id) return 'get_pipeline_status failed: pipeline_id is required (returned by trigger_pipeline).';
|
|
197
|
+
const { getPipeline } = await import('../pipeline');
|
|
198
|
+
const pipeline = getPipeline(params.pipeline_id);
|
|
199
|
+
if (!pipeline) return `Pipeline "${params.pipeline_id}" not found.`;
|
|
200
|
+
const nodes = Object.entries(pipeline.nodes || {}).map(([id, n]) => {
|
|
201
|
+
let line = ` ${id}: ${n.status}`;
|
|
202
|
+
if (n.error) line += ` — ${n.error}`;
|
|
203
|
+
for (const [k, v] of Object.entries(n.outputs || {})) {
|
|
204
|
+
line += `\n ${k}: ${String(v).slice(0, 200)}`;
|
|
205
|
+
}
|
|
206
|
+
return line;
|
|
207
|
+
}).join('\n');
|
|
208
|
+
return `Pipeline ${pipeline.id} [${pipeline.status}] (${pipeline.workflowName})\n${nodes}`;
|
|
209
|
+
},
|
|
210
|
+
|
|
192
211
|
// Surface Forge's local context (projects + agents + skills) so the chat
|
|
193
212
|
// agent can pick valid values for inputs like trigger_pipeline.input.project
|
|
194
213
|
// without guessing. Cheap call — read-only directory + DB lookups.
|
|
@@ -291,6 +310,20 @@ export const BUILTIN_TOOL_DEFS: BuiltinToolDef[] = [
|
|
|
291
310
|
},
|
|
292
311
|
},
|
|
293
312
|
},
|
|
313
|
+
{
|
|
314
|
+
name: 'get_pipeline_status',
|
|
315
|
+
description: "Check a Forge pipeline run's live status + per-node results by id. Pass pipeline_id (returned by trigger_pipeline) to get the run's overall status + each node's status / error / outputs. Use whenever the user asks how a running or finished pipeline is doing.",
|
|
316
|
+
input_schema: {
|
|
317
|
+
type: 'object',
|
|
318
|
+
properties: {
|
|
319
|
+
pipeline_id: {
|
|
320
|
+
type: 'string',
|
|
321
|
+
description: 'Pipeline run id (returned by trigger_pipeline).',
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
required: ['pipeline_id'],
|
|
325
|
+
},
|
|
326
|
+
},
|
|
294
327
|
{
|
|
295
328
|
name: 'list_forge_context',
|
|
296
329
|
description: "Return the current Forge instance's local context: project names (use these as input.project for pipelines / dispatch_task), agent profile ids, and installed skills. Call this whenever the user references a project / agent / skill by name and you need to validate the name OR when picking defaults for trigger_pipeline / dispatch_task. No arguments.",
|
|
@@ -639,6 +639,15 @@ stop_condition: "all agents say DONE"
|
|
|
639
639
|
initial_prompt: "Review PR #{{input.pr_number}} in project {{input.project}}. Reviewer: analyze the diff. Author: be ready to address feedback."
|
|
640
640
|
```
|
|
641
641
|
|
|
642
|
+
## Controlling pipelines from chat
|
|
643
|
+
|
|
644
|
+
The chat assistant has builtin tools for pipelines, so you can run and check them in plain language:
|
|
645
|
+
|
|
646
|
+
- **`trigger_pipeline`** — start a workflow. Ask the assistant to "run the `<name>` pipeline" and it dispatches the run, returning a pipeline run id. Call it with no arguments first and it lists every workflow plus its input schema.
|
|
647
|
+
- **`get_pipeline_status`** — check a run by id. Ask "what's the status of pipeline `<id>`?" and it returns the run's overall status plus each node's status, error, and outputs.
|
|
648
|
+
|
|
649
|
+
Typical flow: trigger a pipeline, note the returned id, then ask the assistant for its status whenever you want an update — no need to open the Pipelines view. The same two tools are exposed to Claude Code over MCP (`trigger_pipeline` / `get_pipeline_status`).
|
|
650
|
+
|
|
642
651
|
## Pipeline Model
|
|
643
652
|
|
|
644
653
|
In **Settings → Pipeline Model**, you can select which Claude model runs pipeline tasks. Set to `default` to use the same model as regular tasks.
|
package/package.json
CHANGED