VS Code Extension¶
The AMI / 3forge Language Support extension (3forge.vscode-ami) brings AmiScript and AMISQL language intelligence and live debugging into VS Code. This page covers installing the extension, connecting it to AmiCore, editing a live Web session, and diagnosing the connection failures that account for most first-run problems.
The extension is a thin client. The language and debug servers run inside AmiCore (see Language and Debug Servers), and the extension connects to them over AmiCore's RPC WebSocket port. It never starts AmiCore itself.
What to expect on a first run
3 things account for most first-run confusion:
- Almost everything is bound to a live Web session. That session is created by logging in to AmiCore's Web UI in a browser, then handing its id to the extension. Until then, the extension gives generic language support and empty views.
- Applying a change neither re-runs the object nor writes it to disk. Re-executing and persisting are separate actions. See Editing a Live Session.
- The connection settings depend on how AmiCore is configured, not on the extension. The REST port and its scheme in particular vary between a stock local build and a shared deployment.
Features¶
- Language support for
.ami(AmiScript) and.amisqlfiles: completion, hover, signature help, diagnostics, and formatting, backed by AmiCore's own parser. - Workspace navigation: go-to-definition, find-references, workspace symbols, and rename across
.amisql/.ami/.properties. - Live debugging: set breakpoints and step through AmiScript callbacks (Web) and Center targets (timers, triggers, procedures, methods).
- Deployment views: browse a live deployment's layouts, session editors, Center debug targets, and documentation from the AMI sidebar.
- Query & run helpers: run and validate AmiScript / AMISQL against the connected instance with a keystroke.
Prerequisites¶
| Requirement | Detail |
|---|---|
| VS Code | 1.75 or newer, plus the extension .vsix |
| A running AmiCore instance | Required for all live features. It must serve the RPC WebSocket endpoint on ami.rpc.ws.port (default 33334) with the LSP plugin loaded. The endpoint binds to loopback by default, so the simplest setup is an AmiCore on the same machine as VS Code. See Language and Debug Servers for additional configuration details |
| Credentials | An AmiCore username and password |
| A browser | To log in and create the Web session the extension binds to |
| Java 17 | Only for Offline Mode. Not needed when connecting to a running AmiCore |
Older builds cannot serve ws mode
The language server ships as a server-side plugin. A build that predates it has no ami.rpc.ws.port in its configuration and no WebSocket to connect to, so the extension cannot bind. If that property is absent from the instance's configuration, or nothing is listening on the port, the build is too old whatever version of the extension is installed.
Install¶
Download the vscode-ami-0.2.35.vsix file from the "Files" section of the 3forge Client Portal, then install it one of 2 ways.
- Open the Extensions view (
Ctrl+Shift+X). - Click the
…menu at the top of the view, then select Install from VSIX… - Select the
.vsixfile. - When prompted, Reload the window.
--force overwrites any previously installed version. Use it when upgrading, otherwise the debug adapter can stay on the previous version.
Windows
The bare code on your PATH may resolve to the GUI launcher, which does not accept --install-extension. Use the CLI launcher under the install's bin directory instead e.g:
"%LOCALAPPDATA%\Programs\Microsoft VS Code\bin\code.cmd" --install-extension <vsix> --force
To confirm what is installed:
Open the Command Palette (Ctrl+Shift+P) and type AMI. The extension's commands appear, and a .ami or .amisql file now opens with AmiScript syntax highlighting. Commands do not appear until the window is reloaded. To upgrade later, install a newer .vsix the same way (with --force on the CLI) and reload the window.
Connect¶
Connecting means pointing the extension at 3 endpoints on the AmiCore host, storing credentials, and binding to a live Web session.
Connection Channels¶
The extension talks to 3 logical endpoints, all on the host given by ami.lsp.host:
| Channel | Endpoint | Used for |
|---|---|---|
| Web UI | the Web port, 33333 HTTPS or 33332 HTTP |
Logging in. This is where the session id comes from |
| REST | /3forge_rest/* on ami.rest.port |
Running queries, listing sessions, applying editor changes |
| WebSocket | /lsp and /dap on ami.websocket.port |
Diagnostics, completion, hover, and step debugging |
Keeping these 3 separate is what makes the common failures legible: a working login proves nothing about REST, and a working REST channel proves nothing about the language server.
Find Your Instance's Values¶
The client settings below are derived from properties on the AmiCore side. Read them from the instance's own configuration: an override in config/local.properties wins, otherwise the shipped defaults.properties applies.
| Read this on AmiCore | Sets this in VS Code |
|---|---|
| The host AmiCore runs on | ami.lsp.host |
ami.rpc.ws.port, default 33334 |
ami.websocket.port |
ami.rest.uses.web.port |
Decides where REST is served, and so the 2 rows below |
...set to a Web component name: that component's own http.port / https.port. A stock install serves HTTPS on 33333 |
ami.rest.port |
...set to false: REST's own socket, ami.rest.http.port or ami.rest.https.port |
ami.rest.port |
| The scheme actually served by whichever port the 2 rows above resolved to | ami.rest.scheme |
ami.db.debug.enabled |
Not a client setting. It must be true before the Center Debug Targets view has anything in it |
A stock local install needs none of this looked up, because the defaults in the next section already match it. Look these up when connecting to a deployment someone else configured, or when the defaults do not work.
Filling in the host and port from a deployment on disk
Where the workspace contains the deployment's own files, the extension can read the connection details rather than having them typed. In Workspace mode, select the instance in the Deployments view and run AMI: Connect. It sets ami.lsp.host and ami.rest.port from that deployment's local.properties, then prompts for the session id.
2 things it does not do, so check both afterwards:
- It does not set
ami.rest.scheme, which stayshttps. The port it picks is the first ofami.port,https.port, orhttp.portfound, so an HTTP-only deployment yields a plain-HTTP port against an HTTPS scheme. That combination fails withEPROTOor "wrong version number". - It writes at workspace scope, not user scope, so the values land in the folder's
.vscode/settings.jsonand override anything set in User Settings.
Set the Connection Settings¶
Open Preferences: Open User Settings (JSON) and add the connection settings. These values suit an AmiCore running locally on stock ports:
| Setting | What it is |
|---|---|
ami.lsp.mode |
Language server transport: auto, ws, or stdio. ws connects to a running AmiCore; stdio runs a local offline linter instead |
ami.lsp.host |
Host of the AmiCore instance. Used for the WebSocket endpoints and the REST channel |
ami.websocket.port |
The extension's name for AmiCore's RPC WebSocket port. Match it to the server's ami.rpc.ws.port, default 33334 |
ami.rest.port |
Port serving /3forge_rest/*. Default 33333 |
ami.rest.scheme |
http or https for that port. The port number does not imply the scheme |
ami.auth.username |
AmiCore username for REST authentication. Default demo |
Match ami.websocket.port to the server's ami.rpc.ws.port
The 2 properties are named differently on each side, and AmiCore has a separate property that happens to share the client's name. The extension's ami.websocket.port must equal AmiCore's ami.rpc.ws.port, which is the endpoint serving /lsp and /dap and defaults to 33334.
AmiCore's own ami.websocket.port is an unrelated, opt-in WebSocket streaming listener for browsers, commented out by default and shipped with ami.websocket.auth.plugin.class=DISABLED. Do not enable it to satisfy the extension.
REST is not always on the Web port
ami.rest.port defaults to 33333, the Web HTTPS port. That is correct only when AmiCore sets ami.rest.uses.web.port to a Web component name, which is the stock default. With ami.rest.uses.web.port=false, common in development so local clients can skip the self-signed certificate, REST binds its own socket in plain HTTP. Point ami.rest.port at ami.rest.http.port and set ami.rest.scheme=http.
Do not copy REST values between deployments. A port that is right for a shared server is usually wrong locally, and the symptom is "Rest not enabled on this port".
Prefer 127.0.0.1 to localhost for a local instance
AmiCore binds the RPC WebSocket to IPv4 loopback by default, through ami.rpc.ws.bindAddress=loopback. On a dual-stack machine, localhost can resolve to ::1 first and the connection is refused, which surfaces as a Node AggregateError and an offline language server. Setting ami.lsp.host to 127.0.0.1 avoids it.
Self-signed certificates need no handling in the extension, because ami.tls.rejectUnauthorized defaults to false. A browser still warns at login, and that warning is safe to proceed past on a development instance.
Bind to a Session¶
- Run AMI: Set Credentials. The password is stored in the OS keychain, not in
settings.json. The username comes fromami.auth.username. - Run AMI: Switch to Live.
- Log in to AmiCore's Web UI to create a session. For a local instance on the Web's HTTPS port that is
https://localhost:33333/3forge, accepting the self-signed certificate. - Run AMI: Set Session ID and supply the session's id. Read it from Dashboard -> Admin Tool -> Sessions, or from
showSessions().__SESSIONID. - (Optional) Set
ami.centerId. Only needed for Center-target debugging where several Centers run in one instance.
The connection is good when the status bar reads AMI LSP · WebSocket .../lsp · session-bound and AMI: Center + Web session, and the AMI activity-bar container fills with Layouts, datamodels, and Center Debug Targets. The status bar reads offline lint rather than session-bound whenever the transport is not ws or no session id is set.
AMI: Show Connection Status reports what the extension currently reaches, and why not where it does not. AMI: Print Language Server Status to Log writes the same detail to the AMI output channel.
Changed connection settings need a window reload
AMI: Restart Language Server does not reliably re-read a changed ami.lsp.host, or other ami.* connection settings. The WebSocket client can keep the stale value and stay disconnected. Run Developer: Reload Window after changing a connection setting, before concluding the new value is wrong.
Offline Mode¶
To lint .ami and .amisql files with no running AmiCore, set ami.lsp.mode to stdio, point ami.lsp.amiHome at an AmiCore installation and ami.lsp.javaHome at a Java 17 JDK, then run AMI: Setup Sidecar (Offline LSP) Mode…. This spawns a local sidecar JVM that runs AmiCore's own parser, giving completion, diagnostics, formatting, and workspace symbols with no session and no login.
The amilsp plugin is compiled for Java 17 and loaded from the install's plugins directory, so the plugin must be present in the installation given by ami.lsp.amiHome.
Live-only features need a running instance: editor-aware callback validation, debugging, and the live deployment views.
auto falls back only when the sidecar is configured
In auto mode the extension tries the WebSocket first and falls back to the sidecar only if both ami.lsp.amiHome and ami.lsp.javaHome are set. With either unset, which is the default, a failed WebSocket connection is reported as an error rather than silently downgraded, and the notification names the missing settings.
Editing a Live Session¶
A live session editor is a temporary file bound to an object in the running session. Opening the object binds the buffer: open a callback or datamodel editor from Web Session Editors, or run AMI: Open in VS Code.
Saving that buffer reaches AmiCore. Because ami.applyOnSave defaults to true, Ctrl+S sends the code and applies it in one step, and the status bar reports Saved + applied. 2 things saving does not do:
- It does not re-execute the object.
- It does not write anything to disk.
The actions available on a bound buffer are:
| Action | What it does |
|---|---|
AMI: Validate (Ctrl+Enter) |
Checks the buffer without sending it. Not a prerequisite for applying |
| AMI: Apply to AMI | Sends the buffer and commits it to the session, after a confirmation prompt |
AMI: Apply & Run (Alt+Enter) |
Applies, then re-executes the object. For a datamodel this runs it immediately |
| AMI: Save to Layout (persist to disk) | Writes the session's layout out to disk |
| AMI: Pull from Live (Discard Local Edits) | Re-fetches the live code over local edits |
Set ami.applyOnSave to false to separate the 2 halves of a save. Saving then stages the code on the server without committing it, reporting Saved (not yet applied), and applying becomes an explicit action. This is worth doing where an applied callback runs on every save.
An applied change is not a persisted change
Applying commits to the running session only. Without Save to Layout, the change is lost when the session ends.
Applying a datamodel does not re-run it
Apply commits the definition. The previous result set stays on screen until something re-executes the datamodel, so a reader who checks the data rather than the definition will conclude the apply failed. Use Apply & Run to apply and re-execute in one step.
Opening a layout switches the session id
Opening a layout from the Layouts view starts a headless session and repoints ami.sessionId at it. Anything applied afterwards goes to that headless session rather than to the browser session being watched, and the apply reports success either way.
Browse layouts first, then run AMI: Set Session ID to point back at the intended session. Where an applied change does not appear, check the target with AMI: Show Connection Status before changing the code.
No .ami file on disk is normal in Live mode
Live editors are session-bound and held in memory. A .ami file appears on disk only after Save to Layout.
A Worked Example: Change a Datamodel and See It Update¶
This is the shortest path that avoids both traps above, the wrong session and the missing re-run. The order matters: bind the session last, after any browsing in the Layouts view.
- Log in to the Web UI in a browser and open the application containing the datamodel.
- Read the session id from Dashboard -> Admin Tool -> Sessions.
- Browse the Layouts view now, if at all. Opening a layout there repoints
ami.sessionIdat a headless session, so anything done in that view belongs before the session is bound. - Run AMI: Set Session ID and supply the id from step 2. Doing this after step 3 is what makes the rest of the sequence land in the right place.
- Open the datamodel's editor from Web Session Editors, not from Layouts. Web Session Editors binds to the session set in step 4, while Layouts opens a layout in a headless session of its own.
- Edit the definition, then press
Ctrl+S. The status bar reportsSaved + applied. - The definition is now live, but the panel still shows the previous result set. Run AMI: Apply & Run (
Alt+Enter) to re-execute the datamodel, and the panel updates. - Run AMI: Save to Layout (persist to disk) to keep the change beyond the session's life.
If the panel does not update after step 7, confirm the target before editing anything further:
- Run AMI: Show Connection Status and check the session id is still the one from step 2. If it is not, a layout was opened in between; re-run AMI: Set Session ID, then Apply & Run again.
- Run AMI: Show DM Output to read the datamodel's current output directly, which separates an apply that did not land from a query returning what it always returned.
- Run AMI: Close Headless Session to discard a headless session created by browsing layouts.
What Needs a Session, and What Does Not¶
ami.sessionId is required for diagnostics, completion, and hover, and for the live panel, datamodel, and layout editors. Saving a bound buffer also does nothing at all, silently, while the session id is unset.
Center SQL queries and the Center Debug Targets, meaning timers, triggers, procedures, and methods, work as soon as AmiCore is reachable and credentials are set, with no Web session at all.
Language and Navigation¶
Language Editing¶
Open any .ami or .amisql file. As you type:
- Completion on
.and:, covering member methods, global functions, keywords, and DDLOFTYPE/USEslots. Local variables complete too, typed to their declared class. - Hover documentation and signature help, on
(and,. - Diagnostics on open, change, and save, produced by AmiCore's real compiler plus AMISQL idiom checks.
- Formatting: Format Document applies AmiCore's canonical formatter.
In ws mode with a session bound, callbacks are validated with their full context, meaning their layout, this, and linked variables, so diagnostics match how the callback actually runs.
Workspace Navigation¶
With a workspace folder open:
- Go to Definition (
F12), including the nearest-prior declaration for shadowed locals. - Find All References (
Shift+F12). - Rename Symbol (
F2), which propagates across.amisql,.ami, and.propertiesfiles. A local variable renames per binding: a shadowed declaration in an inner block is left alone, and a member access that happens to share the name (row.totalnext to a localtotal) is never rewritten. - Workspace symbol search (
Ctrl+T) for tables, columns, named SQL objects, methods, panels, datamodels, and properties.
Note
Save files before renaming. Unsaved buffers are not yet reindexed, so rename ranges resolve against the last-saved content.
The AMI Sidebar¶
The extension contributes an AMI activity-bar container with 2 faces. Switch between them with AMI: Switch to Live and AMI: Switch to Workspace.
Working against a running instance:
| View | Shows |
|---|---|
| Layouts | Layouts available in the live deployment. Opening one starts a headless session |
| Web Session Editors | Open callback and datamodel editors in the live Web session |
| Center Debug Targets | Timers, triggers, procedures, and methods available to debug, each with an inline ▷ Fire action. Requires ami.db.debug.enabled=true on the Center |
Working with files on disk:
| View | Shows |
|---|---|
| Deployments | AmiCore deployments discovered in the workspace, meaning folders with a local.properties, with type, port, and connection status |
| Layout File | The current layout file's structure |
| Workspace Symbols | Tables, columns, named SQL objects, methods, panels, datamodels, and properties |
| References | Results of Find References Here |
Documentation, the 3forge Enterprise reference, is present in both.
Debugging¶
The extension registers an amiscript debug type that attaches VS Code's debugger to AmiCore's in-JVM debug adapter over the WebSocket port. It provides gutter breakpoints, step over, in, and out (F10, F11, Shift+F11), the Call Stack and Variables panels, Watch, hover, and inline values.
There are 2 kinds of target:
- Web callbacks: a datamodel
onProcess, a panel callback, and similar. The callback editor must be open in the session for the target to resolve. - Center targets: a timer, trigger, procedure, or method, debugged through the Center freeze debugger. Requires
ami.db.debug.enabled=trueon the Center, which is off by default and needs a restart.
Quickest Paths¶
- Active editor: open the callback to debug and run AMI: Debug. The extension derives the target from the file.
- Center target: in the Center Debug Targets view, use Attach Debugger to Center Target, set a breakpoint, then use the inline ▷ Fire action to trigger it.
Using launch.json¶
host and port default to ami.lsp.host and ami.websocket.port, and sessionId to ami.sessionId, so most fields can be omitted. handle and target are mutually exclusive. Set breakpoints in the gutter, press F5, and step. For the full target-reference grammar and protocol, see Language and Debug Servers.
A Center attach checks that the named target exists before the session starts, so a typo fails immediately with a message naming the kind and id rather than leaving a breakpoint that can never fire. Target names are case-sensitive.
One controller at a time
A Center attach takes an exclusive claim on the Center debugger, so a second attach is refused with a message naming the holder. The claim is released when the session detaches. Where a client died without releasing it, clear it with center_debug("detach"). The claim does not lock out the center_debug command surface, so an operator can still step or resume a freeze. See Center Debugger.
Methods are signature-only in the code view
The Center exposes no live method body, so Show Debug Target Code on a method shows its signature plus guidance rather than the source. To set a breakpoint, arm the line directly, where line 1 is the CREATE METHOD signature and line 2 the first body statement, or open the body from the schema file. Timers, triggers, and procedures open in full.
Reference¶
Command Reference¶
Almost every command sits under the AMI category, so typing AMI in the Command Palette lists it with its title. The commands below are those belonging to a workflow that cannot be guessed from a title. The rest are refresh, reveal, and filter actions, mostly surfaced as context actions on the sidebar views, and are best found in the palette.
A few actions are not in the palette at all
6 commands are deliberately hidden from the Command Palette and can only be reached from a view, a context menu, or by clicking a tree item. The one that matters is Open Layout (Headless Session), which has no palette entry and no menu entry: it runs when a layout is clicked in the Layouts view. That is why opening a layout repoints the session id without an obvious command having been run. See Editing a Live Session.
Connection and mode
| Command | Purpose |
|---|---|
AMI: Set Credentials |
Store the AmiCore login. The password goes to the OS keychain |
AMI: Set Session ID |
Set the live Web session id |
AMI: Switch to Live / Switch to Workspace |
Toggle the sidebar between the live and workspace view sets |
AMI: Show Connection Status |
What the extension currently reaches, and why not where it does not |
AMI: Connect |
On a Deployments entry in Workspace mode: set ami.lsp.host and ami.rest.port from the discovered deployment, then prompt for the session id |
Language server
| Command | Purpose |
|---|---|
AMI: Restart Language Server |
Reconnect or restart the language server |
AMI: Print Language Server Status to Log |
Connection status, written to the AMI output channel |
AMI: Setup Sidecar (Offline LSP) Mode… |
Configure the offline stdio transport |
AMI: Rebuild Workspace Symbol Index |
Re-index the workspace |
AMI: Show Workspace Index Status |
Inspect the symbol index's state |
AMI: Show Activation Log |
What the extension did on startup, for diagnosing a failure to activate |
Editing live code
| Command | Purpose |
|---|---|
AMI: Open in VS Code |
Open a live session editor as a local file |
AMI: Validate |
Check the buffer without sending it |
AMI: Apply to AMI |
Commit the buffer to the running session |
AMI: Apply & Run |
Apply, then re-execute |
AMI: Pull from Live (Discard Local Edits) |
Re-fetch the live code over local edits |
AMI: Save to Layout (persist to disk) |
Persist the session's layout to disk |
AMI: Show DM Output |
Read a datamodel's current output, to tell an apply that did not land from a query returning what it always did |
AMI: Close Headless Session |
Discard a headless session, including one created by opening a layout |
Queries
| Command | Purpose |
|---|---|
AMI: New Query Editor |
Open a scratch query editor |
AMI: Run Query (current selection or document) |
Run the selection, or the whole document |
Debugging
| Command | Purpose |
|---|---|
AMI: Debug |
Attach the debugger to the active editor's callback |
AMI: Attach Debugger to Center Target |
Start a Center debug session |
AMI: Show Debug Target Code |
Open a Center target's source |
AMI: Fire Center Target |
Trigger a timer, procedure, or method to drive a breakpoint |
AMI: New… (create from template) / Edit Definition (drop & recreate) |
Create a Center target, or redefine an existing one |
Settings Reference¶
Connection
| Setting | Default | Purpose |
|---|---|---|
ami.lsp.host |
localhost |
Host of the AmiCore instance, used for the WebSocket endpoints and the REST channel |
ami.websocket.port |
33334 |
AmiCore's RPC WebSocket port, hosting both /lsp and /dap. The AmiCore-side property is ami.rpc.ws.port |
ami.rest.port |
33333 |
Port serving /3forge_rest/*. 33333 is the Web HTTPS port and is right only where AmiCore has ami.rest.uses.web.port=<Web component>. Otherwise use ami.rest.http.port or ami.rest.https.port |
ami.rest.scheme |
https |
Scheme for ami.rest.port. The port number does not imply the scheme, and AmiCore's standalone REST socket is commonly plain HTTP |
ami.auth.username |
demo |
AmiCore login username. The password lives in the OS keychain, set via AMI: Set Credentials |
ami.sessionId |
(none) | Live Web session id, the Web session's __SESSIONID |
ami.centerId |
(none) | Target Center for Center debugging, in multi-Center deployments |
ami.tls.rejectUnauthorized |
false |
Whether to verify TLS certificates. Development instances typically use self-signed certificates |
ami.tls.caCertPath |
(none) | CA certificate used to verify AmiCore's certificate when rejectUnauthorized is on |
Language server
| Setting | Default | Purpose |
|---|---|---|
ami.lsp.mode |
auto |
Transport: auto, ws, or stdio |
ami.lsp.amiHome |
(none) | Offline mode: the AmiCore install, given as the install root, its lib directory, or a marker jar directly |
ami.lsp.javaHome |
(none) | Offline mode: the Java 17 JDK used to spawn the sidecar JVM |
ami.lsp.sidecarVmArgs |
[] |
Extra JVM arguments for the sidecar, appended after the required Java 17 --add-opens flags |
ami.lsp.reconnectDelayMs |
3000 |
Delay before reconnecting after a dropped connection |
ami.schema.autoRefreshMs |
30000 |
How often to refresh the live Center schema, feeding the completion cache and Center Debug Targets. 0 disables it |
Editing
| Setting | Default | Purpose |
|---|---|---|
ami.applyOnSave |
true |
Whether saving a bound editor applies the change as well as sending it |
Deployment discovery
These affect Workspace mode only, where the extension scans for folders containing a local.properties:
| Setting | Default | Purpose |
|---|---|---|
ami.deployment.env |
{} |
Per-workspace environment snapshot for resolving ${env.VAR} in local.properties. Takes precedence over ami.deployment.envFiles |
ami.deployment.envFiles |
[] |
Env files, KEY=VALUE per line, consulted during discovery. Earlier files win on conflict |
ami.deployment.exclude |
[] |
Extra folder names to skip, additive with the built-in defaults |
Keybinding Reference¶
| Action | Keybinding | Applies to |
|---|---|---|
| AMI: Apply & Run | Alt+Enter |
.ami files |
| AMI: Validate | Ctrl+Enter |
.ami and .amisql files |
| AMI: Run Query | Ctrl+Shift+Enter |
.ami and .amisql files |
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| Commands do not appear after install | The window was not reloaded | Reload the VS Code window |
| Nothing happens on save, with no message | ami.sessionId is not set, so the save is discarded silently |
Run AMI: Set Session ID |
| An applied change does not appear, but the apply reported success | ami.sessionId points at a headless session, created by opening a layout from the Layouts view |
Run AMI: Set Session ID with the intended session id, then apply again |
| A datamodel's definition applied, but its data did not change | Apply commits the definition without re-executing it | Run AMI: Apply & Run |
| An applied change is lost when the session ends | The change was never persisted | Run AMI: Save to Layout (persist to disk) |
| Connected, but no diagnostics or completion | No session id, or it points at a session that has ended | Re-run AMI: Set Session ID |
| Editor-aware features missing, generic types only | Session id not set | Run AMI: Set Session ID |
| "Rest not enabled on this port", queries failing as unparseable, or an empty Layouts view | ami.rest.port points at a port AmiCore does not serve REST from |
Match the server's REST configuration, and set ami.rest.scheme to suit |
REST errors mentioning EPROTO or "wrong version number" |
Speaking HTTPS to a plain-HTTP REST port | Set ami.rest.scheme=http |
REST fails with 401 |
No stored password | Run AMI: Set Credentials |
No completion in ws mode |
The language server is unreachable | Check that ami.websocket.port matches the server's ami.rpc.ws.port, that ami.rpc.ws.plugin.classes includes LSP, and that the port is listening |
| A changed connection setting appears to have no effect | AMI: Restart Language Server does not reliably re-read ami.* connection settings |
Run Developer: Reload Window |
"AMI language server offline", with a Node AggregateError in the output channel |
ami.lsp.host is localhost, resolving to ::1 on a dual-stack machine, while the endpoint binds IPv4 loopback |
Set ami.lsp.host to 127.0.0.1, then reload the window |
"AMI Language Server offline" in auto mode |
The WebSocket failed and no sidecar is configured | Start AmiCore, or set ami.lsp.amiHome and ami.lsp.javaHome to allow the fallback |
| The login page never loads, or the connection times out | The Web or RPC ports are not reachable. A remote deployment's ports are often firewalled | Use a local instance, or have the ports opened |
| Certificate warnings in the browser | Development instances use self-signed certificates | Proceed past the warning. The extension itself accepts them by default |
| "Configured debug type 'amiscript' is not supported" | The extension was not reinstalled after an upgrade | Reinstall the .vsix with --force, then reload |
| The Center Debug Targets view is empty | The Center debugger is off | Set ami.db.debug.enabled=true on the Center and restart it |
| Debug attach fails to resolve the target | Wrong handle or target, or the target is unavailable |
Verify the target id. For a Web callback, make sure its editor is open in the session |
| A breakpoint never hits | The code did not run, or the line is wrong | Trigger the callback, or use Fire Center Target after attaching |