Keeps your VS Code workspace in sync with a remote AS5 (AppStack5) server. Files upload when you save, download when the server version changes, and conflicts are resolved interactively — with TypeScript compiled to ES5 the way AS5 expects it.
Features
- Bidirectional sync — upload on save, download on open/tab switch, ETag-based conflict detection
- TypeScript for AS5 — compiles
.tson save to ES5 using a bundled TypeScript 6, type-checked against the whole project, with full IntelliSense for the AS5 runtime globals - Explorer badges — see at a glance what is synced (
✓), has pending changes (!), or was never uploaded (?) - Sidebar panels — connections, open conflicts, and an activity log
- Force Pull / Force Push — overwrite a whole folder in either direction, with confirmation
- Browser login — token is captured automatically and stored in the OS keychain
- Service file navigation — jump from any
.js/.tsfile to the AS5 service file that includes it
Requirements
- VS Code 1.82 or later
- Network access to your AS5 server
Getting started
1. Install
Extensions → ⋯ → Install from VSIX… and pick the .vsix file.
2. Run Setup
Command Palette (Ctrl+Shift+P / Cmd+Shift+P) → AS5B: Setup.
It creates four files in your workspace root — existing files are never overwritten:
| File | Purpose |
|---|---|
.as5bridge-config.json |
Sync configuration — opens automatically for editing |
tsconfig.json |
TypeScript settings targeting ES5 for AS5 |
as5.d.ts |
Type declarations for the AS5 runtime globals |
.vscode/settings.json |
Hides .as5b metadata files from the explorer and search |
3. Configure
{
"host": "https://your-as5-host",
"root": "/",
"directories": ["/api/", "/varlibs/", "/web/"],
"extensions": ["js", "ts", "html", "css", "less", "json", ""],
"ignore": ["**/data/"],
"tscCheckExclude": ["/web/"],
"maxParallelRequest": 20
}
| Field | Description |
|---|---|
host |
Base URL of your AS5 server. Only the origin is used — any path is merged into root automatically |
root |
Remote path prefix; your workspace root maps to host + root. Default "/" |
directories |
Remote directories to sync. Start and end with / |
extensions |
Extensions to include. "" matches files without an extension. Include "json" so AS5 config dotfiles (.access.json, .caching.json) sync |
ignore |
Gitignore-style patterns to exclude (matched against the remote path without the leading /) |
tscCheckExclude |
Gitignore-style patterns for .ts files that are transpiled emit-only — ES5 output and upload, but no type-check. Use for standalone frontend code (Vue/Angular) whose browser globals the AS5 tsconfig does not know. Default ["/web/"] |
maxParallelRequest |
Max concurrent HTTP requests. Default 20 |
4. Log in
Click the key icon in the status bar, or run AS5B: Login. A browser opens for authentication; the token is handed back to the extension automatically and a full sync starts.
The token is kept in the OS keychain (VS Code SecretStorage) — never in the config file and never in plain text on disk. It survives restarts; AS5B: Abmelden removes it.
Commands
| Command | Description |
|---|---|
| AS5B: Setup | Create config, tsconfig.json, as5.d.ts and workspace settings |
| AS5B: Synchronize all files | Full sync of all configured directories |
| AS5B: Synchronize current file | Sync only the active file |
| AS5B: Diff gegen Dev-Server | Compare the active file against the dev server. Usually identical — the sync keeps them in step |
| AS5B: Diff gegen Live | Compare the active file against the deployment target. This is the interesting one |
| AS5B: Login (Token erneuern) | Start the browser login flow |
| AS5B: Abmelden (Token entfernen) | Delete the stored token from the keychain |
| AS5B: Sync pausieren / fortsetzen | Toggle auto-sync |
| AS5B: Force Pull (Remote → Lokal) | Server state overwrites all local files in scope |
| AS5B: Force Push (Lokal → Remote) | Local state overwrites all remote files in scope |
| AS5B: Lokale Sync-Dateien entfernen (Reinit) | Delete local .as5b metadata and re-download. Does not touch the server |
| AS5B: AS5-Typdefinitionen (as5.d.ts) anlegen/aktualisieren | Write the AS5 type declarations into the workspace |
| AS5B: Zum Service-File springen | Jump to the service file including the current file |
| AS5B Deploy: Mit Live vergleichen | List the differences between dev and the deployment target |
| AS5B Deploy: Aktuelle Datei hinzufügen | Stage the active file (pulls in its .ts/.js companion) |
| AS5B Deploy: Nachricht setzen | Set the deployment message |
| AS5B Deploy: Review — Diffs prüfen und bestätigen | Walk through the staged files one by one: diff, then confirm or drop |
| AS5B Deploy: Deployment ausführen | Write the confirmed files to the target |
| AS5B Deploy: Letztes Deployment zurückrollen | Restore the state captured before the last deployment |
| AS5B Deploy: Historie | Browse past deployments, roll back a specific one |
| AS5B Deploy: Bei Live anmelden | Log in to the deployment target (separate token) |
| AS5B: Log anzeigen | Open the AS5Bridge output channel |
| AS5B: Dokumentation öffnen | Open the AS5 documentation |
Clicking the status bar item opens a context-sensitive menu with the actions that make sense right now.
How it works
Status indicators
| Explorer badge | Meaning | Status bar | Meaning | |
|---|---|---|---|---|
✓ |
Synced | $(cloud) |
Connected, idle | |
! |
Local changes pending | $(sync~spin) |
Syncing | |
? |
In scope, never synced | $(key) / $(lock) |
Login required / token rejected | |
| ⠋ | TypeScript compiling | $(debug-pause) |
Paused | |
| (none) | Outside the sync scope | $(circle-slash) |
No configuration |
Several backends in one workspace share a single status bar entry showing
icons with counts ($(cloud) 4, $(sync~spin) 2 $(key) 1) instead of one entry
per folder — four connections used to fill the whole bar. The tooltip lists every
folder with its state, and clicking lets you pick one. Set
as5bridge.statusBar.mode to detailed to always list them by name, or
compact to always use counts.
Sync triggers
| Event | Action |
|---|---|
| File saved or created | Upload (debounced 300 ms) |
| File(s) deleted | Batched into one prompt → conditional delete (if-match) |
| File opened / tab switched | Check the server version, download if newer |
| Folder moved or copied in | Contained files are uploaded at the new location |
| Server-side deletion | Reported after a sync; local cleanup offered in one prompt |
.as5bridge-config.json saved |
Reload, then sync only the newly added scope |
Conflicts
When local and remote both changed, you choose: Lokal aktualisieren, Remote überschreiben, or Diff anzeigen. With many conflicts at once, the "Immer …" options apply your choice to the rest of that run.
Files that fail to upload land in the Offene Konflikte panel with one-click retry, survive a restart, and are retried automatically after a login.
TypeScript support
Saving a .ts file type-checks it against the whole project (like tsc -p, so
namespaces split across files resolve), emits ES5 next to the source, and
uploads the .js. Compilation runs in a worker thread — the editor never
blocks, and the tab shows a spinner while it works. Type errors are reported in
the output channel but do not block the upload.
The bundled compiler is pinned to TypeScript 6.x: the AS5 backend only
accepts ES5, and TypeScript 7 removed target: "es5" entirely. The globally
installed tsc is never used, so results do not depend on the machine.
AS5 runtime declarations (as5.d.ts)
AS5 injects globals such as request, response, system, ContentBlob,
XTDate, JSScript, Capability and registerRequestHandler. The extension
ships documented type declarations for all of them, includes them in every
compile, and copies them into your workspace so IntelliSense and hover docs work.
The file is extension-managed and updates itself when a newer version ships —
put project-specific declarations in a separate .d.ts rather than editing it.
Deployment (Dev → Live)
Copying backend files between systems by hand is how a file ends up with the content of a different file. The deployment flow makes that mistake visible before it reaches production: nothing is written to the target until every file has been confirmed in a diff.
Configuration
"deploy": {
"label": "Live",
"host": "https://live-host.ecs.appstackfive.com",
"root": "/", // optional, defaults to the dev root
"compareMode": "sinceLastDeployment", // | "folder" | "full"
"protectedPaths": ["/api/payment/"],
"allowDeletions": false,
"webhook": {
"url": "https://chat.googleapis.com/v1/spaces/…",
"notify": ["success", "failure", "rollback"]
}
}
Without a deploy section the feature stays off. The target has its own
login — run AS5B Deploy: Bei Live anmelden; the token is stored separately
in the OS keychain.
Workflow
- Mit Live vergleichen — lists what differs: changed, only in dev (new), only on live. Because dev and live are independent AS5 systems their ETags are not comparable, so content is compared — hence the three scopes: since last deployment (default, fast), a folder, or everything.
- Stage the files, either from the comparison result or with
AS5B Deploy: Aktuelle Datei hinzufügen. Selecting
foo.tspulls infoo.jsautomatically — deploying only one of them would leave live running the old compilate. - Nachricht setzen — appears in the journal and in the chat channel.
- Review: each file opens as a diff live ↔ dev and must be confirmed individually. Files with warnings require an extra confirmation.
- Deployen — a final modal lists the files, highlighting deletions and
protected paths. Each write is guarded by the
if-matchcaptured during the review, so a file changed on live in the meantime aborts the deployment instead of being overwritten.
Safeguards
| Check | Why |
|---|---|
| Similarity warning | If the new content shares almost nothing with the live version, the file is flagged — this is the "wrong file content" case |
| Unsynced changes | Warns when the local file was never synced to dev, or has unsaved edits — you would deploy a stale version |
| Missing companion | Warns when a .ts is deployed without its .js (or vice versa) |
| Protected paths | Configured globs require an extra confirmation |
if-match |
Aborts if the target changed between review and deployment |
Journal and rollback
Every deployment is recorded under .as5bridge/deployments/ together with the
target's previous content. That directory ignores itself via git and is
excluded from syncing, since it holds production data.
AS5B Deploy: Letztes Deployment zurückrollen restores that state. AS5B Deploy: Historie lists past deployments and can roll back a specific one.
No atomicity. AS5 has no transaction across files. If file 7 of 10 fails, the deployment stops there and reports a partial state — it does not pretend to be all-or-nothing. A rollback is offered immediately.
Chat notification
Successful, failed and rolled-back deployments are posted to the configured Google Chat webhook:
*Deployment → Live* · Markus Enderlein <[email protected]>
> Bugfix im Bestellprozess
• `/api/order/checkout.js`
• `/api/order/checkout.ts`
*🗑 Gelöscht (1):*
• `/api/order/legacy.js`
3 Dateien · 27.07.2026 14:32 · ✅ erfolgreich
A webhook that is unreachable is logged and ignored — it never turns a successful deployment into a failed one.
Command line (as5b)
The same core that drives the extension is also available as a CLI — for scripts, CI, and AI assistants that work in a terminal.
npm i -g ./extension # or: npm link, from the extension directory
as5b --help
as5b status # config, login state, deployment target
as5b login [--deploy] # browser login (dev or target)
as5b diff api/order.js [--live] # local file vs. dev (or the deployment target)
as5b pull [/api/] # download from dev
as5b push [files...] # upload to dev
as5b watch # upload on save, propagate deletions
as5b deploy compare --mode full # differences dev ↔ live
as5b deploy plan api/order.js # what would happen, incl. warnings
as5b deploy run api/order.js -m "Fix" # deploy, with a diff review per file
as5b deploy rollback # undo the last deployment
as5b deploy history
Every command accepts --json and then writes a single JSON document to
stdout — diagnostics go to stderr, so the output stays parseable:
as5b deploy compare --json | jq '.differences[] | select(.suspicious)'
Automation and safety
The CLI enforces the same safeguards as the editor — a diff review per file,
the preflight checks, if-match on every write:
| Flag | Effect |
|---|---|
| (none) | Interactive: unified diff per file, confirmation required |
--yes |
Skips the routine per-file confirmation. Blocking warnings still stop the deployment |
--force |
Also overrides blocking warnings and destructive confirmations (deletion, rollback). Recorded as "forced" in the journal and the chat message |
For pull/push, conflicts (both sides changed since the last sync) are asked
interactively; --conflict local|remote|skip decides upfront. Without a
terminal the default is skip — neither side is discarded silently.
--dry-run reports what would happen without writing.
That split is deliberate: automation is possible, but a file that looks like a
different file, is unsynced, or sits on a protected path does not slip through
just because a script passed --yes.
Exit codes
Chaining with && has to be safe, so anything short of a clean run is non-zero:
| Code | Meaning |
|---|---|
0 |
Everything went through |
1 |
Errors, unresolved conflicts, blocking warnings on deploy plan, an explicitly named file outside the sync scope, or a cancelled run |
2 |
Unknown command |
Bad flag values are rejected rather than silently defaulted — --mode ful,
--mode folder without --folder, --conflict bogus, or --id without a value
(which would have rolled back the newest deployment) all stop with an error.
Authentication
The CLI cannot read the extension's tokens — VS Code's SecretStorage is only reachable from the editor. It uses, in order:
AS5_TOKEN/AS5_DEPLOY_TOKENfrom the environment (CI, agents)~/.as5bridge/credentials.json, written with mode600byas5b login
Metadata files
Each synced file gets a small .as5b sidecar holding the remote ETag and a
dirty flag. Setup hides them from the explorer. Reinit removes them all and
re-downloads from the server without modifying anything remotely.
Deployment workflow
- AS5B Deploy: Mit Live vergleichen — find what differs from the target
- AS5B Deploy: Aktuelle Datei hinzufügen (or click a difference in the sidebar)
- AS5B Deploy: Nachricht setzen — what is being shipped
- AS5B Deploy: Review — one diff per file, each confirmed individually
- AS5B Deploy: Deployment ausführen
Every step is a Command Palette entry; the Deployment sidebar shows the same flow with buttons. Nothing is written to the target before step 4 is complete.
Troubleshooting
"Diff gegen Dev-Server" never shows a difference.
That is expected: AS5Bridge uploads on save, so the workspace and the dev server
are kept identical. Use AS5B: Diff gegen Live (or as5b diff --live) to see
what actually differs from production.
A file does not sync.
Check that its directory is listed in directories and its extension in
extensions — both must match. .service.js and other dotfiles do sync;
files inside hidden directories (.cache/) never do. AS5B: Log anzeigen
shows the decision for every file.
TypeScript errors in frontend files (window/document unknown, Vue
redeclared).
Those files are standalone browser scripts, not AS5 modules. Add their path to
tscCheckExclude to compile them emit-only.
"Metadatei korrupt".
The .as5b sidecar is unreadable. Delete it — the file re-syncs on the next
save — or run Reinit for a clean slate.
Everything asks for a login again.
The token was rejected (status bar shows $(lock)). Log in again; queued files
are retried automatically.
The remote file is newer and you want to look first. AS5B: Diff gegen Remote shows both versions side by side without changing anything.
Links
Licensed under the MIT License.