@jslee124/forge 0.3.0 → 0.3.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/dist/index.js +1189 -90
- package/package.json +2 -1
- package/resources/docs/en/ARCHITECTURE.md +519 -0
- package/resources/docs/en/AUTHENTICATION.md +224 -0
- package/resources/docs/en/CLI_UI.md +266 -0
- package/resources/docs/en/CONFIGURATION.md +263 -0
- package/resources/docs/en/CONTEXT_MANAGEMENT.md +692 -0
- package/resources/docs/en/GETTING_STARTED.md +241 -0
- package/resources/docs/en/PLUGINS.md +622 -0
- package/resources/docs/en/PRODUCT.md +157 -0
- package/resources/docs/en/PROJECT_CONTEXT.md +225 -0
- package/resources/docs/en/RELEASING.md +94 -0
- package/resources/docs/en/SECURITY.md +272 -0
- package/resources/docs/en/SESSIONS.md +134 -0
- package/resources/docs/en/TROUBLESHOOTING.md +256 -0
- package/resources/docs/index.json +24334 -0
- package/resources/docs/zh-CN/ARCHITECTURE.md +174 -0
- package/resources/docs/zh-CN/AUTHENTICATION.md +96 -0
- package/resources/docs/zh-CN/CLI_UI.md +112 -0
- package/resources/docs/zh-CN/CONFIGURATION.md +221 -0
- package/resources/docs/zh-CN/CONTEXT_MANAGEMENT.md +200 -0
- package/resources/docs/zh-CN/GETTING_STARTED.md +193 -0
- package/resources/docs/zh-CN/PLUGINS.md +286 -0
- package/resources/docs/zh-CN/PRODUCT.md +86 -0
- package/resources/docs/zh-CN/PROJECT_CONTEXT.md +130 -0
- package/resources/docs/zh-CN/RELEASING.md +86 -0
- package/resources/docs/zh-CN/SECURITY.md +92 -0
- package/resources/docs/zh-CN/SESSIONS.md +69 -0
- package/resources/docs/zh-CN/TROUBLESHOOTING.md +185 -0
- package/resources/skills/forge-plugin-creator/SKILL.md +70 -0
- package/resources/skills/forge-plugin-creator/references/plugin-api.md +36 -0
- package/resources/skills/forge-plugin-creator/templates/index.mjs +30 -0
- package/resources/skills/forge-plugin-creator/templates/plugin.json +8 -0
- package/resources/skills/forge-plugin-creator/templates/plugin.test-template.ts +14 -0
- package/resources/skills/forge-product-help/SKILL.md +16 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Security Model
|
|
2
|
+
|
|
3
|
+
简体中文 · Documentation index
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
This document defines Forge's implemented security model through Milestone 10.
|
|
8
|
+
Built-in tools stay inside the selected workspace, every valid tool action
|
|
9
|
+
passes through a policy decision, and approval-required actions are denied when
|
|
10
|
+
no approval channel is available. The `safe` and `workspace-write` permission
|
|
11
|
+
profiles are implemented. Persisted sessions restore completed conversation
|
|
12
|
+
only, and every resumed run receives fresh policy and approval state;
|
|
13
|
+
`full-access` remains deferred.
|
|
14
|
+
|
|
15
|
+
Context checkpoints are derived, untrusted conversation memory. They cannot
|
|
16
|
+
carry approvals, trust decisions, permission profiles, or current verification
|
|
17
|
+
status. Fresh instructions and the current request remain mandatory; the
|
|
18
|
+
canonical transcript is retained separately. Provider-native opaque context is
|
|
19
|
+
treated as sensitive state and is never exposed to plugin observers or ordinary
|
|
20
|
+
trace payloads.
|
|
21
|
+
|
|
22
|
+
## Principle
|
|
23
|
+
|
|
24
|
+
Forge is safe by default, but approval is not the same as isolation. The product
|
|
25
|
+
must state which boundaries it enforces and which risks remain with the user.
|
|
26
|
+
|
|
27
|
+
## Default decisions
|
|
28
|
+
|
|
29
|
+
| Action | Default decision |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| Read, list, or search inside the workspace | Allow |
|
|
32
|
+
| First write inside the workspace | Confirm |
|
|
33
|
+
| Later writes covered by the run approval | Allow |
|
|
34
|
+
| Any process command | Confirm |
|
|
35
|
+
| Any registered network tool | Confirm |
|
|
36
|
+
| Any delegated subagent model run | Confirm |
|
|
37
|
+
| Built-in file operation outside the workspace | Deny in v0.1 |
|
|
38
|
+
| Approval-required action without an approval channel | Deny |
|
|
39
|
+
|
|
40
|
+
Narrow outside-workspace approvals are a possible later feature. They are not
|
|
41
|
+
part of v0.1, so a repository task cannot expand Forge's file-tool boundary by
|
|
42
|
+
asking the user for an exception.
|
|
43
|
+
|
|
44
|
+
## Permission profiles
|
|
45
|
+
|
|
46
|
+
### `safe`
|
|
47
|
+
|
|
48
|
+
The default profile. Workspace reads are automatic. Workspace modifications,
|
|
49
|
+
process commands, registered network tools, and delegated subagent model runs
|
|
50
|
+
require confirmation according to the table above.
|
|
51
|
+
|
|
52
|
+
### `workspace-write`
|
|
53
|
+
|
|
54
|
+
Workspace file tools may modify files automatically after the user selects this
|
|
55
|
+
profile. Process commands, registered network tools, and delegated subagent
|
|
56
|
+
model runs still require confirmation, and outside-workspace file access
|
|
57
|
+
remains denied in v0.1.
|
|
58
|
+
|
|
59
|
+
### `full-access`
|
|
60
|
+
|
|
61
|
+
Deferred until after v0.1. A future explicit advanced mode would require clear
|
|
62
|
+
warnings and a user decision; a project file or plugin could never enable it
|
|
63
|
+
silently. Forge will not expose a profile whose name implies isolation it does
|
|
64
|
+
not provide.
|
|
65
|
+
|
|
66
|
+
## Configuration boundary
|
|
67
|
+
|
|
68
|
+
Forge treats `~/.forge/config.json` as user-controlled configuration. Project
|
|
69
|
+
`.forge/config.json` may override ordinary project behavior but cannot set a
|
|
70
|
+
less restrictive permission profile, mark the project trusted, suppress a
|
|
71
|
+
mandatory approval, increase a user-defined safety limit, or enable a plugin
|
|
72
|
+
from an untrusted project.
|
|
73
|
+
|
|
74
|
+
API keys, OAuth credentials, and other secrets are invalid in both user and
|
|
75
|
+
project configuration. User configuration may reference a provider or
|
|
76
|
+
credential name, while the secret value comes from an environment variable or
|
|
77
|
+
Forge's owner-readable credential file. ChatGPT subscription credentials stay
|
|
78
|
+
inside Codex App Server's credential boundary.
|
|
79
|
+
|
|
80
|
+
Forge must validate configuration before loading plugins or starting a run. It
|
|
81
|
+
should warn when user configuration or user-plugin directories have unsafe
|
|
82
|
+
filesystem permissions on platforms where that check is meaningful.
|
|
83
|
+
|
|
84
|
+
## Filesystem boundary
|
|
85
|
+
|
|
86
|
+
Built-in file tools resolve canonical paths and symlinks before applying policy.
|
|
87
|
+
Paths inside the selected workspace can follow the active permission profile.
|
|
88
|
+
Paths outside it are denied in v0.1.
|
|
89
|
+
|
|
90
|
+
Local image attachments are a separate, user-authorized input capability.
|
|
91
|
+
Forge accepts an outside-workspace path only when the user explicitly supplies
|
|
92
|
+
it with `--image`, pastes or drags it into the interactive composer, or selects
|
|
93
|
+
an in-workspace `@` mention. Forge never infers attachments from ordinary
|
|
94
|
+
prompt prose, repository content, or model output. The model's filesystem tools
|
|
95
|
+
remain workspace-confined.
|
|
96
|
+
|
|
97
|
+
Before encoding a local attachment, Forge resolves its canonical path, requires
|
|
98
|
+
a regular readable file, validates JPEG/PNG/GIF/WebP magic bytes, and enforces
|
|
99
|
+
per-image, combined-size, and count limits. User-supplied HTTP(S) image URLs are
|
|
100
|
+
sent to the selected provider for retrieval; Forge does not fetch them itself.
|
|
101
|
+
Session snapshots and ordinary run events do not persist base64 image bytes.
|
|
102
|
+
|
|
103
|
+
The policy applies to Forge file tools. It does not automatically constrain a
|
|
104
|
+
child process that has already been approved.
|
|
105
|
+
|
|
106
|
+
## Process boundary
|
|
107
|
+
|
|
108
|
+
The v0.1 `run_command` tool accepts a program and an argument array and starts it
|
|
109
|
+
with Node.js `spawn` using `shell: false`. Shell syntax such as pipelines,
|
|
110
|
+
redirection, command substitution, and compound commands is not accepted.
|
|
111
|
+
|
|
112
|
+
Every process command requires confirmation in the default profile. The
|
|
113
|
+
approval prompt must show at least:
|
|
114
|
+
|
|
115
|
+
- The exact program and individually quoted arguments
|
|
116
|
+
- The working directory
|
|
117
|
+
- The timeout
|
|
118
|
+
- The requested environment changes, when relevant
|
|
119
|
+
|
|
120
|
+
Starting a process with its working directory inside the workspace does not stop
|
|
121
|
+
it from reading or writing elsewhere. Without an operating-system sandbox,
|
|
122
|
+
Forge cannot claim filesystem or network isolation for an approved child
|
|
123
|
+
process. `shell: false` stops Forge itself from parsing shell expressions; it
|
|
124
|
+
does not prevent an approved program, such as a package manager, from starting
|
|
125
|
+
other processes or interpreting its own scripts.
|
|
126
|
+
|
|
127
|
+
## Network boundary
|
|
128
|
+
|
|
129
|
+
The runtime distinguishes registered network tools from workspace reads. A
|
|
130
|
+
plugin must declare `network:access` before registering a `network`-risk tool,
|
|
131
|
+
and every such model call requires confirmation under both `safe` and
|
|
132
|
+
`workspace-write`. Non-interactive runs deny it when no approval channel is
|
|
133
|
+
available.
|
|
134
|
+
|
|
135
|
+
The checked-in `web-tools` example additionally restricts protocols and ports,
|
|
136
|
+
checks initial and redirect host addresses, blocks local/private/reserved
|
|
137
|
+
ranges, accepts readable MIME types only, and bounds redirects, time,
|
|
138
|
+
downloads, and retained output. Those checks reduce accidental SSRF and
|
|
139
|
+
resource exhaustion, but they cannot provide OS-level network isolation or
|
|
140
|
+
fully eliminate DNS rebinding between validation and connection.
|
|
141
|
+
|
|
142
|
+
An approved process command or trusted plugin code may still access the network
|
|
143
|
+
directly with the permissions of the Forge process. Manifest capabilities gate
|
|
144
|
+
Forge registration APIs; they do not constrain arbitrary Node.js calls. The UI
|
|
145
|
+
and documentation must not imply otherwise.
|
|
146
|
+
|
|
147
|
+
## Delegated model runs
|
|
148
|
+
|
|
149
|
+
Subagent tools use the separate `model` risk and require confirmation on every
|
|
150
|
+
call, including under `workspace-write`, because they incur another model run.
|
|
151
|
+
The approval view shows the generated tool name and delegated task. The host
|
|
152
|
+
creates the child adapter and never exposes credentials to the plugin.
|
|
153
|
+
|
|
154
|
+
Children inherit the effective parent policy and approval channel, receive only
|
|
155
|
+
declared non-subagent tools, share bounded run/step/tool budgets, use the same
|
|
156
|
+
workspace and abort signal, and return bounded output. Recursive delegation is
|
|
157
|
+
not available. With tracing enabled, child events are stored in a separate
|
|
158
|
+
trace linked by `parentRunId` and `subagentName`; the parent tool result records
|
|
159
|
+
the child run ID. This is runtime containment, not provider or OS isolation.
|
|
160
|
+
|
|
161
|
+
## Non-interactive operation
|
|
162
|
+
|
|
163
|
+
If an operation requires approval and no approval channel is available, Forge
|
|
164
|
+
denies the operation unless the user supplied a narrow approval before the run.
|
|
165
|
+
Non-interactive mode must never interpret silence as approval.
|
|
166
|
+
|
|
167
|
+
The evaluation harness may provide an approval channel that approves only the
|
|
168
|
+
exact program, arguments, working directory, and timeout declared by a fixture.
|
|
169
|
+
It is test infrastructure, not a general bypass.
|
|
170
|
+
|
|
171
|
+
## Plugin trust
|
|
172
|
+
|
|
173
|
+
In-process JavaScript plugins are trusted local code. They can call Node.js APIs
|
|
174
|
+
directly and therefore may read files, start processes, or use the network
|
|
175
|
+
outside Forge's tool API.
|
|
176
|
+
|
|
177
|
+
Forge's plugin API prevents plugins from weakening core policy through supported
|
|
178
|
+
hooks, but this is not isolation from malicious plugin code. Project-local
|
|
179
|
+
plugins require an explicit project-trust decision before loading. Strong plugin
|
|
180
|
+
isolation requires a separate process or operating-system sandbox.
|
|
181
|
+
|
|
182
|
+
Project trust is keyed by the canonical workspace path and stored outside the
|
|
183
|
+
repository under the user-level Forge home. A repository-controlled `.forge/`
|
|
184
|
+
file cannot mark the project trusted. Forge must not execute code from
|
|
185
|
+
`.forge/plugins/` during discovery or before the user makes that trust decision.
|
|
186
|
+
|
|
187
|
+
## Repository-provided instructions
|
|
188
|
+
|
|
189
|
+
`AGENTS.md`, `.agents/`, and non-executable `.forge/` configuration are
|
|
190
|
+
repository-controlled input. They may influence the model and therefore may
|
|
191
|
+
contain prompt injection, but they cannot approve tool calls, enable
|
|
192
|
+
`full-access`, or weaken a core policy decision.
|
|
193
|
+
|
|
194
|
+
Skills and configuration are not executed merely because they are discovered.
|
|
195
|
+
Skill discovery reads bounded metadata; `load_skill` accepts only registered
|
|
196
|
+
opaque IDs, revalidates canonical roots, non-symlink regular files, and the
|
|
197
|
+
discovered file identity, and returns bounded content. It does not widen the
|
|
198
|
+
workspace `read_file` boundary. Any referenced script or requested action still
|
|
199
|
+
passes through the normal tool, approval, and trace pipeline. Forge records
|
|
200
|
+
Skill discovery, source, selection reason, load rejection, and truncation so
|
|
201
|
+
the user can inspect the effective context.
|
|
202
|
+
|
|
203
|
+
## Reasoning visibility
|
|
204
|
+
|
|
205
|
+
Reasoning or thinking content returned by the model provider is visible to the
|
|
206
|
+
user by default. Forge must identify it as provider-supplied content and must not
|
|
207
|
+
claim access to reasoning that the provider did not return.
|
|
208
|
+
|
|
209
|
+
Reasoning content may contain repository data or other sensitive information.
|
|
210
|
+
Trace persistence and export must use the same redaction policy as model and
|
|
211
|
+
tool events.
|
|
212
|
+
|
|
213
|
+
## Persistent sessions
|
|
214
|
+
|
|
215
|
+
Resuming a session restores completed conversation messages, not executable
|
|
216
|
+
authority. Forge creates a new policy instance for every resumed run and never
|
|
217
|
+
restores prior approvals, pending tool calls, child processes, or provider
|
|
218
|
+
continuation metadata. Current user configuration and project instructions are
|
|
219
|
+
loaded again before the next prompt.
|
|
220
|
+
|
|
221
|
+
Session snapshots and traces are stored outside the repository under
|
|
222
|
+
`FORGE_HOME`. They may contain repository text, diffs, commands, and model
|
|
223
|
+
output, so they are local sensitive data even after configured credentials are
|
|
224
|
+
redacted.
|
|
225
|
+
|
|
226
|
+
## Credential handling
|
|
227
|
+
|
|
228
|
+
DeepSeek/OpenAI API keys, access tokens, refresh tokens, authorization codes,
|
|
229
|
+
and PKCE verifiers
|
|
230
|
+
are secrets. They must never appear in prompts, traces, terminal debug output,
|
|
231
|
+
plugin events, crash reports, or repository files.
|
|
232
|
+
|
|
233
|
+
Forge currently resolves API keys from process environment variables first,
|
|
234
|
+
then from the explicit `$FORGE_HOME/auth.json` fallback. The fallback is stored
|
|
235
|
+
outside the project, written atomically, protected by directory mode `0700` and
|
|
236
|
+
file mode `0600`, and documented as sensitive plaintext storage rather than an
|
|
237
|
+
operating-system keychain. OS credential-store integration remains a preferred
|
|
238
|
+
future improvement.
|
|
239
|
+
|
|
240
|
+
Provider/model/reasoning selections are ordinary configuration and may be
|
|
241
|
+
saved under `FORGE_HOME`; credentials remain separate. Credential-shaped
|
|
242
|
+
fields and known secret values are redacted before traces and plugin observers
|
|
243
|
+
receive events.
|
|
244
|
+
|
|
245
|
+
OAuth token refresh must be single-flight so concurrent model requests do not
|
|
246
|
+
race to rotate the same refresh token. Logout clears Forge-owned credentials.
|
|
247
|
+
Forge must not silently import or modify another application's credential file.
|
|
248
|
+
|
|
249
|
+
For ChatGPT subscription access, Forge delegates OAuth and refresh to the
|
|
250
|
+
official Codex App Server. Forge sends account JSON-RPC requests but never reads
|
|
251
|
+
Codex's credential file or receives its tokens. This account is shared Codex
|
|
252
|
+
state, so the explicit `forge auth logout openai` command may also sign other
|
|
253
|
+
local Codex clients out.
|
|
254
|
+
|
|
255
|
+
Codex Engine security semantics are separate from the native Forge policy
|
|
256
|
+
kernel. Its `safe` profile maps to Codex read-only sandboxing. Users must select
|
|
257
|
+
`workspace-write` explicitly to let Codex modify the workspace. Codex tool
|
|
258
|
+
events do not pass through Forge's built-in/plugin tool policy or native JSONL
|
|
259
|
+
trace pipeline; the CLI labels this execution path rather than implying they do.
|
|
260
|
+
|
|
261
|
+
## Out of scope for v0.1
|
|
262
|
+
|
|
263
|
+
- A hardened operating-system sandbox
|
|
264
|
+
- Guaranteed network isolation
|
|
265
|
+
- Isolation from malicious trusted plugins
|
|
266
|
+
- Reliable prevention of prompt injection
|
|
267
|
+
- Protection after the user explicitly approves a harmful command
|
|
268
|
+
- Treating another application's private OAuth integration as a stable public API
|
|
269
|
+
- Built-in file access outside the selected workspace
|
|
270
|
+
- Shell-language execution and compound shell commands
|
|
271
|
+
|
|
272
|
+
Packaged product documentation uses a separate allowlisted resource catalog. Search returns opaque, versioned document/section references; reads revalidate the file, content hash, package version, and output budget. The documentation tools reject arbitrary paths and do not widen workspace file access. Skill and documentation text remains untrusted and cannot grant permissions, expose secrets, or authorize commands.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Persistent Sessions and Run Traces
|
|
2
|
+
|
|
3
|
+
简体中文 · Documentation index
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Forge persists enough trusted metadata and completed conversation history to
|
|
8
|
+
continue an interactive chat after the process exits. This is deliberately
|
|
9
|
+
separate from replaying an in-progress tool call.
|
|
10
|
+
|
|
11
|
+
The core relationship is:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
Session
|
|
15
|
+
|-- completed user/assistant turns
|
|
16
|
+
|-- provider-exposed reasoning summaries for completed assistant turns
|
|
17
|
+
|-- optional derived context checkpoint
|
|
18
|
+
|-- workspace and working-directory metadata
|
|
19
|
+
`-- Run 1 -> events.jsonl
|
|
20
|
+
Run 2 -> events.jsonl
|
|
21
|
+
Run 3 -> events.jsonl
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
A **session** is the user-facing conversation selected by `forge resume` or
|
|
25
|
+
`/resume`. A **run** is one bounded agent-loop execution for one submitted
|
|
26
|
+
prompt. Resuming a session creates a new run inside that session.
|
|
27
|
+
|
|
28
|
+
## Storage layout
|
|
29
|
+
|
|
30
|
+
Milestone 6 uses transparent local files rather than a database:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
$FORGE_HOME/
|
|
34
|
+
|-- sessions/
|
|
35
|
+
| `-- <session-id>.json
|
|
36
|
+
`-- runs/
|
|
37
|
+
`-- <run-id>.jsonl
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Session snapshots use `schemaVersion: 2`; v1 snapshots migrate on load. Trace
|
|
41
|
+
envelopes retain `schemaVersion: 1`. Files are written only under the resolved
|
|
42
|
+
Forge home. Session snapshots are replaced atomically. Run traces are append-only
|
|
43
|
+
while their run is active.
|
|
44
|
+
|
|
45
|
+
Each session stores:
|
|
46
|
+
|
|
47
|
+
- Session ID, creation time, and last-updated time
|
|
48
|
+
- Canonical workspace root and the saved working directory
|
|
49
|
+
- Completed user and assistant messages
|
|
50
|
+
- Provider-exposed reasoning text associated with completed assistant messages
|
|
51
|
+
- The ordered run IDs belonging to the session
|
|
52
|
+
- An optional versioned checkpoint with source/tail hashes and provenance
|
|
53
|
+
|
|
54
|
+
Each trace line is a versioned envelope containing the run ID, optional session
|
|
55
|
+
ID, sequence number, timestamp, and one structured `RunEvent`. Subagent trace
|
|
56
|
+
envelopes additionally carry `parentRunId` and `subagentName`; the parent trace
|
|
57
|
+
links back through the completed delegation tool result.
|
|
58
|
+
|
|
59
|
+
## Resume behavior
|
|
60
|
+
|
|
61
|
+
Forge supports:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
forge resume <session-id>
|
|
65
|
+
forge resume --last
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The interactive `/resume` command opens a bounded list of saved sessions for
|
|
69
|
+
the current canonical workspace. Selecting one replaces the empty/current
|
|
70
|
+
conversation with its completed history and continues in that saved session.
|
|
71
|
+
|
|
72
|
+
Resume follows these rules:
|
|
73
|
+
|
|
74
|
+
1. Only completed user/assistant turns and their provider-exposed reasoning are
|
|
75
|
+
restored for display.
|
|
76
|
+
2. A new prompt always starts a new bounded run with a new run ID.
|
|
77
|
+
3. Current configuration and `AGENTS.md` instructions are loaded again.
|
|
78
|
+
4. Approval state is new for every resumed run.
|
|
79
|
+
5. Provider continuation records and partially completed tool calls are never
|
|
80
|
+
resumed.
|
|
81
|
+
6. A saved session from another workspace is rejected unless the user starts
|
|
82
|
+
from that workspace explicitly.
|
|
83
|
+
7. Missing or invalid session files produce an actionable configuration-style
|
|
84
|
+
error without starting a model request.
|
|
85
|
+
8. A valid checkpoint restores the same bounded active view; a stale or invalid
|
|
86
|
+
checkpoint is ignored without changing the canonical transcript.
|
|
87
|
+
|
|
88
|
+
This means Forge restores conversation context, not authority or executable
|
|
89
|
+
state. Saved reasoning remains display-only and is not added to the model's
|
|
90
|
+
conversation history. Providers may expose only a reasoning summary, not their
|
|
91
|
+
private internal chain of thought; Forge saves only the text actually emitted.
|
|
92
|
+
For Codex App Server turns, Forge explicitly requests a detailed reasoning
|
|
93
|
+
summary and renders the streamed summary notifications.
|
|
94
|
+
|
|
95
|
+
## Inspect behavior
|
|
96
|
+
|
|
97
|
+
`forge inspect <run-id>` reads and validates the corresponding JSONL trace,
|
|
98
|
+
then renders an event timeline plus duration, model steps, tool calls, token
|
|
99
|
+
usage, context-budget categories, retained/omitted messages, estimation error,
|
|
100
|
+
and terminal status. Inspection never executes tools or contacts the model
|
|
101
|
+
provider.
|
|
102
|
+
|
|
103
|
+
Terminal rendering and trace persistence consume the same `RunEvent` objects.
|
|
104
|
+
The trace is therefore evidence of the runtime path, rather than a second log
|
|
105
|
+
assembled from terminal strings.
|
|
106
|
+
|
|
107
|
+
## Redaction and safety
|
|
108
|
+
|
|
109
|
+
Before persistence, Forge redacts configured credential values and recognized
|
|
110
|
+
secret-bearing fields. In particular, `DEEPSEEK_API_KEY` must never appear in a
|
|
111
|
+
session snapshot or run trace.
|
|
112
|
+
|
|
113
|
+
Run traces may still contain repository contents, diffs, commands, model text,
|
|
114
|
+
and provider-returned reasoning. Files under `sessions/` and `runs/` are local
|
|
115
|
+
sensitive data and must not be committed to a repository.
|
|
116
|
+
|
|
117
|
+
Session resume does not weaken the existing security model:
|
|
118
|
+
|
|
119
|
+
- Previous approvals are not restored.
|
|
120
|
+
- A previous permission profile is not trusted as a grant; current user
|
|
121
|
+
configuration and explicit CLI choices determine the next run.
|
|
122
|
+
- Project files cannot edit session metadata under `FORGE_HOME` through
|
|
123
|
+
built-in workspace file tools.
|
|
124
|
+
- Inspecting or listing sessions is read-only and performs no model call.
|
|
125
|
+
|
|
126
|
+
## Deferred behavior
|
|
127
|
+
|
|
128
|
+
- Resuming in the middle of an active model stream or tool call
|
|
129
|
+
- Branching or forking a session
|
|
130
|
+
- Cross-machine synchronization
|
|
131
|
+
- SQLite indexing
|
|
132
|
+
- Deleting canonical transcript history through a retention policy
|
|
133
|
+
- Cross-provider reuse of provider-native opaque checkpoints
|
|
134
|
+
- Trace encryption
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
简体中文 · Documentation index
|
|
4
|
+
|
|
5
|
+
Start with the read-only checks below. They reveal most setup problems without
|
|
6
|
+
contacting a model or changing the repository.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
node --version
|
|
10
|
+
pnpm --version
|
|
11
|
+
pnpm forge --version
|
|
12
|
+
pnpm forge config validate
|
|
13
|
+
pnpm forge config show
|
|
14
|
+
pnpm forge plugins list
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Forge requires Node.js 24 or newer and the repository pins pnpm 11.18.0. When a
|
|
18
|
+
command fails, keep the first actionable error line; later provider or session
|
|
19
|
+
errors may be consequences of the same configuration problem.
|
|
20
|
+
|
|
21
|
+
## Install or build fails
|
|
22
|
+
|
|
23
|
+
### pnpm wants to replace `node_modules` in a non-interactive environment
|
|
24
|
+
|
|
25
|
+
Use CI mode so pnpm does not wait for a terminal prompt:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
CI=true pnpm install --frozen-lockfile
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then rebuild:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm build
|
|
35
|
+
pnpm check
|
|
36
|
+
pnpm test
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### The global `forge` command does not reflect source changes
|
|
40
|
+
|
|
41
|
+
`pnpm link:global` links the built CLI, not TypeScript source at runtime. Rebuild
|
|
42
|
+
the checkout:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm build
|
|
46
|
+
forge --version
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Confirm which executable your shell sees with `command -v forge`. If the link
|
|
50
|
+
is no longer wanted, run `pnpm unlink:global`.
|
|
51
|
+
|
|
52
|
+
## Configuration is invalid or surprising
|
|
53
|
+
|
|
54
|
+
Run:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pnpm forge config validate
|
|
58
|
+
pnpm forge config show
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Common causes are malformed JSON, an unknown field, a missing
|
|
62
|
+
`"schemaVersion": 1`, or a user-only field inside project `.forge/config.json`. Project files may
|
|
63
|
+
set only stricter `limits` and `context` values. The `show` output includes each
|
|
64
|
+
setting's source so an environment or CLI override is visible.
|
|
65
|
+
|
|
66
|
+
If `FORGE_HOME` is set, Forge does not use `~/.forge` for that process. Check
|
|
67
|
+
the `Forge home:` line before editing a file.
|
|
68
|
+
|
|
69
|
+
## API authentication fails
|
|
70
|
+
|
|
71
|
+
### `Missing DEEPSEEK_API_KEY` or `Missing OPENAI_API_KEY`
|
|
72
|
+
|
|
73
|
+
Open interactive Forge and use `/login` to save a key, or export the named
|
|
74
|
+
variable:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
export DEEPSEEK_API_KEY="your-api-key"
|
|
78
|
+
# or
|
|
79
|
+
export OPENAI_API_KEY="your-api-key"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Environment values win over `$FORGE_HOME/auth.json`. Inspect the source without
|
|
83
|
+
printing the key:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pnpm forge auth status deepseek
|
|
87
|
+
pnpm forge auth status openai-api
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If `/logout` reports that an environment variable remains active, unset it in
|
|
91
|
+
the parent shell yourself. A child process cannot edit its parent's
|
|
92
|
+
environment.
|
|
93
|
+
|
|
94
|
+
### ChatGPT subscription and OpenAI API were confused
|
|
95
|
+
|
|
96
|
+
They are separate access routes:
|
|
97
|
+
|
|
98
|
+
- `OPENAI_API_KEY` uses the usage-based OpenAI API through the native Forge
|
|
99
|
+
Engine.
|
|
100
|
+
- `forge auth login openai` and `forge codex ...` use ChatGPT subscription
|
|
101
|
+
access through Codex App Server.
|
|
102
|
+
|
|
103
|
+
Forge never converts one into the other. See Authentication.
|
|
104
|
+
|
|
105
|
+
### A stored compatible-route key stopped working after an endpoint change
|
|
106
|
+
|
|
107
|
+
Stored route credentials are bound to the canonical `baseUrl`. Forge refuses
|
|
108
|
+
to send an old key to a different endpoint. Open `/login`, select the route,
|
|
109
|
+
and save a new credential after reviewing the URL.
|
|
110
|
+
|
|
111
|
+
### Provider request fails before authentication
|
|
112
|
+
|
|
113
|
+
Errors such as DNS lookup failure, connection refusal, TLS failure, or timeout
|
|
114
|
+
happen before a provider can accept or reject the key. Check network access,
|
|
115
|
+
the route's `baseUrl`, proxy variables, and whether a local server is running.
|
|
116
|
+
Do not rotate or paste credentials until the transport layer is reachable.
|
|
117
|
+
|
|
118
|
+
## ChatGPT or Codex Engine setup fails
|
|
119
|
+
|
|
120
|
+
Confirm that Codex CLI is installed and available, then inspect the shared
|
|
121
|
+
account and model catalog:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pnpm forge auth status openai
|
|
125
|
+
pnpm forge models list --provider openai
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Use device-code login when a browser callback is unavailable:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pnpm forge auth login openai --method device-code
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`forge auth logout openai` operates on the shared Codex account and may sign
|
|
135
|
+
other local Codex clients out. Forge does not read or repair Codex's credential
|
|
136
|
+
file directly.
|
|
137
|
+
|
|
138
|
+
## A write, command, network request, or subagent was denied
|
|
139
|
+
|
|
140
|
+
Under `safe`, the first write in each native run requires confirmation. Every
|
|
141
|
+
process command, registered network-tool call, and delegated model run also
|
|
142
|
+
requires confirmation. Under `workspace-write`, file writes are automatic, but
|
|
143
|
+
the latter three actions still require confirmation.
|
|
144
|
+
|
|
145
|
+
When stdin/stderr are not TTYs, a one-shot native run has no approval channel;
|
|
146
|
+
confirmation-required actions are denied. This is expected fail-closed
|
|
147
|
+
behavior. Run in a terminal, narrow the task to read-only behavior, or use a
|
|
148
|
+
purpose-built automation/evaluation approval channel. Do not switch profiles
|
|
149
|
+
expecting OS isolation: neither profile sandboxes an approved process.
|
|
150
|
+
|
|
151
|
+
## A project plugin is listed but skipped
|
|
152
|
+
|
|
153
|
+
Project plugins are discovered from the canonical workspace root's
|
|
154
|
+
`.forge/plugins/` directory but are not imported before trust. Review the code,
|
|
155
|
+
then use either the interactive `/plugins` panel or:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pnpm forge plugins list
|
|
159
|
+
pnpm forge plugins trust
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
For an explicit non-interactive trust decision:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pnpm forge plugins trust --yes
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Trust is stored outside the repository and is keyed to the canonical workspace
|
|
169
|
+
path. A copied or moved checkout needs a new decision. User plugins instead
|
|
170
|
+
live under `$FORGE_HOME/plugins` and must be named in `plugins.enabled`.
|
|
171
|
+
|
|
172
|
+
The Codex Engine owns a separate tool runtime and does not load Forge plugins.
|
|
173
|
+
|
|
174
|
+
## `web_search` or `web_fetch` is unavailable
|
|
175
|
+
|
|
176
|
+
These are not built-in tools. They come from the optional checked-in
|
|
177
|
+
`examples/plugins/web-tools` example. Install and enable that plugin explicitly,
|
|
178
|
+
then restart Forge and confirm the startup resource panel lists it.
|
|
179
|
+
|
|
180
|
+
If requests fail behind a proxy, the example honors `HTTP_PROXY`,
|
|
181
|
+
`HTTPS_PROXY`, and `NO_PROXY` (plus lowercase aliases). Configure an HTTP or
|
|
182
|
+
mixed proxy endpoint, not a SOCKS-only port. Direct and `NO_PROXY` destinations
|
|
183
|
+
retain private/reserved-address checks. See the example README.
|
|
184
|
+
|
|
185
|
+
## Reasoning is missing or marked unavailable
|
|
186
|
+
|
|
187
|
+
Forge renders and persists only reasoning text the provider actually exposes.
|
|
188
|
+
Positive reasoning-token usage does not guarantee that the API returned a
|
|
189
|
+
displayable summary or delta. Forge will not invent hidden chain of thought.
|
|
190
|
+
|
|
191
|
+
Check the selected provider, model, and effort:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
pnpm forge config show
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Then use `/model` and `/effort` to select a capability advertised by the
|
|
198
|
+
provider. If answers stream normally but reasoning is explicitly unavailable,
|
|
199
|
+
the limitation may be upstream rather than a terminal rendering failure.
|
|
200
|
+
|
|
201
|
+
## Image attachment fails
|
|
202
|
+
|
|
203
|
+
Forge accepts JPEG, PNG, GIF, and WebP, with at most 8 images, 20 MiB each, and
|
|
204
|
+
40 MiB total. It validates file magic bytes rather than trusting the extension.
|
|
205
|
+
The selected native model must declare image support.
|
|
206
|
+
|
|
207
|
+
User-pasted or `--image` paths are explicit attachment authorization and may be
|
|
208
|
+
outside the workspace. Model-invoked file tools remain workspace-confined.
|
|
209
|
+
Check for a readable regular file, supported format, size limit, and compatible
|
|
210
|
+
model. Session files do not persist base64 image data.
|
|
211
|
+
|
|
212
|
+
## Resume cannot find or open a session
|
|
213
|
+
|
|
214
|
+
Sessions are workspace-bound. Start Forge inside the same canonical repository
|
|
215
|
+
and try:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
pnpm forge resume --last
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Session snapshots live under `$FORGE_HOME/sessions`. Changing `FORGE_HOME`,
|
|
222
|
+
moving the checkout, deleting a snapshot, or corrupting its JSON changes what
|
|
223
|
+
is available. Resume restores only completed turns; it cannot continue an
|
|
224
|
+
interrupted stream or pending tool call.
|
|
225
|
+
|
|
226
|
+
## Terminal input or rendering looks wrong
|
|
227
|
+
|
|
228
|
+
- Enter submits.
|
|
229
|
+
- Shift+Enter inserts a newline in supported terminals.
|
|
230
|
+
- Ctrl+J is the portable multiline fallback.
|
|
231
|
+
- Ctrl+C closes a menu first, cancels a run second, and exits only when idle.
|
|
232
|
+
- `NO_COLOR` disables color; redirected output uses plain terminal-safe text.
|
|
233
|
+
|
|
234
|
+
Forge has specific keyboard handling for VS Code and Ghostty. If a terminal
|
|
235
|
+
cannot distinguish Shift+Enter, use Ctrl+J. Record the terminal name, `TERM`,
|
|
236
|
+
and the exact key behavior when reporting a reproducible issue; do not include
|
|
237
|
+
credentials or private trace content.
|
|
238
|
+
|
|
239
|
+
## Collect a safe diagnostic bundle
|
|
240
|
+
|
|
241
|
+
Before opening an issue, capture only non-secret output:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
node --version
|
|
245
|
+
pnpm --version
|
|
246
|
+
pnpm forge --version
|
|
247
|
+
pnpm forge config validate
|
|
248
|
+
pnpm forge plugins list
|
|
249
|
+
git rev-parse --short HEAD
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Also include the command, expected behavior, first actionable error, operating
|
|
253
|
+
system, terminal, and whether the run used Forge Engine or Codex Engine. If a
|
|
254
|
+
native trace exists, `forge inspect <run-id>` can summarize it, but review the
|
|
255
|
+
result before sharing: traces may contain repository text, diffs, commands,
|
|
256
|
+
model output, and provider-exposed reasoning.
|