@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.17
1
+ # Forge v0.10.18
2
2
 
3
3
  Released: 2026-05-30
4
4
 
5
- ## Changes since v0.10.16
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
@@ -1678,7 +1678,7 @@ function AgentTerminalButton({ projectPath, projectName }: { projectPath: string
1678
1678
  currentSessionId,
1679
1679
  });
1680
1680
  } catch {
1681
- openTerminal(a.id);
1681
+ openTerminal(a.id, false);
1682
1682
  }
1683
1683
  };
1684
1684
 
@@ -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
- const detail: any = { projectPath: info.projectPath, projectName: info.projectName, agentId: info.agentId, profileEnv: info.profileEnv };
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
  }}
@@ -280,7 +280,12 @@ export function resolveTerminalLaunch(agentId?: string): TerminalLaunchInfo {
280
280
  }
281
281
 
282
282
  return {
283
- cliCmd: cli.cmd,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.10.17",
3
+ "version": "0.10.18",
4
4
  "description": "Unified AI workflow platform — multi-model task orchestration, persistent sessions, web terminal, remote access",
5
5
  "type": "module",
6
6
  "scripts": {