Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>AISDLC CompanionNew to Visual Studio Code? Get it now.
AISDLC Companion

AISDLC Companion

Comarch S.A.

|
1 install
| (0) | Free
Human interface for AISDLC forges: connect your services, start a forge for a ticket, and follow the agents and repositories of the forge.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

AISDLC Companion

Code name forge. Maintained by the AISDLC team.

A VS Code extension that gives humans a dedicated interface to AISDLC forges. A forge normally runs in GitLab CI. With the companion you start a forge for one ticket on your own machine, follow what the agents produced, and work on the repositories of the ticket.

The extension is client- and ticket-agnostic. A forge is a fork of forge-blueprint named <client>-forge on GitLab and is shown as forge-<client>.

Pages and views

Welcome (editor tab)

Command AISDLC: Welcome / Overview, or the home icon in the Forges view title. It opens by itself on the first window after the extension is installed, and after an update it offers a What's New button instead of opening on its own.

It is the entry point of the extension: a live status summary (services connected, Docker, forges on this machine), one card per page with a button that opens it, the three steps of starting a forge, and links to your GitLab and Jira hosts once they are configured.

Setup (editor tab)

Command AISDLC: Open Setup, or the gear in the Forges view. One card per service, each with a Connect button that opens a dialog. The dialog tests the credentials before saving them.

Service Used for
GitLab Lists your forges and their tickets, fetches the default branch of a forge. Token scopes: api, read_repository, read_registry
Jira Ticket summaries; the agents read and update the ticket
AI model provider FACTORY_API_KEY or POLARIS_API_KEY, used by the agents
Container registry docker login to the registry of the pipeline image the base environment is built on

Tokens are stored encrypted in VS Code secret storage. A token saved here wins over the same variable in the OS environment; Disconnect falls back to the OS value. Tokens never go to settings, logs or command lines.

Below the cards, the page checks Docker, Git, the Dev Containers extension and local forge folders. On Windows, when docker is only a .cmd wrapper around WSL, the extension detects it and calls wsl --exec docker directly.

Start a Forge (editor tab)

Command AISDLC: Start a Forge, or + in the Forges view. The page titles itself Create Forge, under a Home > Create Forge breadcrumb, the way the landing page and the forge dashboard do.

  • Forge: a dropdown of your GitLab projects named <client>-forge, plus forge folders cloned on this machine. A GitLab forge is listed without its forge- marker (acme), a local folder under the name it was added with.
  • Ticket: a table with one row per ticket and a column per field (Ticket, Summary, Status, Branch), not a dropdown. Tickets come from agents/tickets/index.yaml of the forge, plus every agent/<ticket> branch, ordered alphabetically by id (ABC-9 before ABC-10). Summaries and statuses come from Jira when it is connected. One row is selected at a time, and the selected row is the ticket the forge is started for.
  • Ticket detail: once a ticket is picked, its title, description, labels and current assignee appear below the list, with a link to the issue in Jira. The title, description, labels and assignee come from Jira; the description falls back to the index.yaml entry.
  • Flow and Role: the flow defaults to the one named by the ticket's agent:<flow>_xxx label (the first such label wins), then to the one in the ticket's forge status.

The branch is implied by the ticket: the container always works on its agent/<ticket> branch, which it creates when it does not exist yet. There is nothing to choose.

Start Forge then runs four steps, shown live on the page:

  1. Fetch forge: shallow clone of the repository's default branch into a temporary folder. The GitLab token is passed through GIT_CONFIG_* environment variables only and is never written to the clone. Skipped when the forge's base environment is already built.
  2. Build base environment: builds one image per forge locally, from the docker/Dockerfile shipped with this extension. The clone is the build context, so the image carries the whole framework; the build recipe itself comes from the extension, so a forge branch cannot change how a forge is built. Skipped when it is already built.
  3. Start forge: starts a fresh container on that base image with your connected tokens. The entrypoint fetches and checks out the ticket's agent/<ticket> branch, then the framework clones the ticket's repositories itself. CI_JOB_TOKEN is set to a fixed placeholder: the framework refuses an empty value, but a local run has no job token and never uses it as a credential.
  4. Prepare the workspace: waits for the container to say it is done preparing. docker run --detach returns as soon as the container exists, while the checkout and the clone above are still running, so the launch follows the container's log until the entrypoint logs setup complete; container remains attachable. The step counts the seconds it has waited; the page closes and the landing page opens only then, so it paints a flow that can be read instead of spinning for the seconds the clone takes. A preparation that fails, stops, or takes over ten minutes keeps the page, its log and the container, and says which of the three it was.

The image is per forge and flow-agnostic: <forge>-base, everything lowercased — forge-of-the-forge-base. It is built the first time a forge is started on this machine and kept until you remove it, so a second ticket of the same forge starts straight away. The container stays per ticket/flow/role: <forge>-<flow>-<JIRA_ID>, with the stage appended when a role is chosen — forge-of-the-forge-dev-aisdlct-177, or forge-of-the-forge-dev-developer-aisdlct-177 for the developer role of the dev flow.

Because the base is a snapshot, it does not pick up new commits on the default branch on its own. Remove Base Environment on the forge row drops it; the next launch rebuilds it. It is refused while a container of that forge still runs on it. When a container for the ticket already exists, the page offers to use it or replace it.

The per-ticket images an earlier version built (<forge>-<flow>-<ticket>) are no longer addressed by anything in the UI: nothing runs on them once their containers are gone, so docker image prune reclaims them.

Once the forge has started, this tab closes itself and the landing page of the new forge opens in its place: the stages of its flow, and the reports the agents produce as they run. A launch that fails, or that is refused because a forge already exists, keeps the page open with the log instead.

Landing page (editor tab)

Command AISDLC: Open Landing Page, or the graph icon on the row of a running forge — and what opens when a forge starts. It shows where the ticket stands in the flow of its forge:

INTSP-3033 · dev                                     status: dev_to_implement
┌────────────────┐   ┌────────────────┐   ┌────────────────┐
│ Dev Classifier │ → │ Dev Developer  │ → │ Dev Reviewer   │
│ classifier     │   │ developer      │   │ reviewer       │
│ done           │   │ current        │   │ did not run    │
│ 00-ticket.md   │   │ 02-plan.md     │   │ 05-review.md   │
│ 01-analysis.md │   │ 03-impl…md     │   │ 04-test.md     │
│ 02-plan.md     │   │ 04-test.md     │   │                │
└────────────────┘   └────────────────┘   └────────────────┘

This is the global flow: every stage of the flow, side by side, left to right — the overview of where the ticket stands. It is not the chronological record; that is the Run history below, which lists the stages as they actually ran, one row each, in the order they happened.

dev_to_implement is what the classifier leaves behind, and what triggers the developer: the classifier is past, the developer is current, the reviewer has not run. The reports the last two promise are struck through until they are written.

The stages come from the container itself, not from a list kept in the extension. Each role of the flow carries a pipeline.yml (automated-flow/<flow>/<role>/pipeline.yml) whose variables describe it: STATUS_TRIGGER is the ticket status that starts the role, STATUS_SUCCESS the one it leaves behind, STATUS_WORKING the one it sets while it runs, STATUS_FAILURE the one it leaves on failure, and FORGE_ARTIFACT_EXPECTED the markdowns it is expected to write.

A forge that keeps no such files declares its stages in its .gitlab-ci.yml instead. The extension then reads the root CI file and every file it include:s locally, concatenates them, resolves each job's extends: (a job with none is a root; a job that extends one is merged into it, its own variables winning and its before_script/script/after_script appended after the parent's), and takes the jobs that declare both FORGE_FLOW and FORGE_STAGE for the flow being read — those jobs carry the same STATUS_* and FORGE_ARTIFACT_EXPECTED variables the per-role files do.

The order of the chart is read from those statuses: when the STATUS_SUCCESS of a stage is the STATUS_TRIGGER of another, the two are chained, and the chart follows the chain from the stage nothing triggers. A stage the chain does not reach is still shown, after the others, so a role is never silently dropped.

The colors come from the ticket's status in the forge's agents/tickets/index.yaml:

Color Meaning
green the ticket is past the stage: it ran
yellow the stage is the current one — its trigger, or its working status
red the ticket holds a STATUS_FAILURE; the stage shown is the one whose run failed, which is the one the history below records as failed (every role of a flow often shares one failure status, so the status alone cannot say) — the last stage that produced artifacts when no history is readable
gray the ticket is before the stage: it did not run
gray (all) the status matches nothing in this flow, so the chart shows no progress rather than guessing

Under each stage is the list of the markdowns FORGE_ARTIFACT_EXPECTED promises, matched against the reports of the ticket in /workspace/agents/tickets/<ticket>/<flow>/ (the ticket folder when the reports are there instead). An entry that is not there yet is shown struck through. Clicking one opens it in VS Code's own markdown preview, in the column beside the landing page — the extension renders no markdown of its own. Refresh re-reads the container, so the chart follows a running forge.

Below the chart, a Run history section — folded by default — holds the literal record of agents/tickets/<ticket>/.jira-pipeline/rows.tsv: one row per pipeline run, in the order it happened, running down the page and joined by a downward link, with the role, start time, status, duration, summary and a link to the pipeline in GitLab. Where the chart shows a stage once, the history shows it as many times as it ran, so a retry, or a loop back to a stage the ticket had already passed, is visible — a run that returns to a stage the ticket had passed is drawn as a step back rather than forward. Each stage tile of the chart also carries a quiet count (2 runs · last 09:34 · 1 failed) once it has run.

The history lists every run of the ticket, including the ones recorded by a flow this container does not carry — a qa container whose ticket went through dev stages — but the chart itself stays on this container's own flow.

Each run card also lists what that step produced, folded into a quiet count at the foot of the card (3 artifacts ▸). A stage commits its artifacts as <FORGE_JOB_NAME>: <TICKET> and persists its state separately as <FORGE_JOB_NAME>: finalize <TICKET>; only the first is read, so the list holds the work of the stage rather than the framework's bookkeeping. In the orchestrator those are the agents' reports — the numbered NN-*.md files; the notes under agents/memory/, index.yaml and the per-job JSON say nothing about what the stage produced, so they are left out. In a repository the ticket cloned under repositories/, the whole commit is the artifact, because that commit is the code change. A run is matched to its commit by the job name — Dev Developer and Developer name the same role — and by time, so a retry gets its own commit, and a run that failed before committing anything lists none rather than borrowing its neighbour's.

The list keeps the shape of the repository: the files of each repository sit in a foldable tree whose folders unfold like the Explorer's, rather than in one flat run of full paths. A folder whose only child is another folder is joined with it into one node (src/main/java/com/comarch/), so a Java package shows as the single path it is instead of a chain of folders that each hold nothing.

Clicking an artifact opens it in VS Code's own diff editor, against the revision of the file before that commit: an added file against an empty document, a modified one against its previous version. The diff opens beside the landing page, which keeps the left half of the window, and each further artifact is added as a tab of that same right column rather than replacing the one before it — so the page stays put while each artifact's diff waits its turn. Both sides are read out of git through the forge:// provider, so the diff shows what that one run changed even after later runs have moved the file on, and neither side can be saved over the live file.

A forge prepares its workspace with git clone --depth 1, and the framework clones the ticket's repositories as blobless partial clones, so neither carries more than its tip: the commits a stage produced are not there to be listed, and without help every card of every container would claim its stage wrote nothing. The extension therefore widens the history first, in place and in one call (git fetch --unshallow per clone), and only then reads the log — which is why the reports of the orchestrator (00-ticket.md, 01-analysis.md, …) now appear where a shallow workspace used to list none. The widen writes into .git, which the image owns as root, so that one call runs as root; the log itself stays an ordinary read as the container user. A clone the widen cannot reach — an unreachable remote — stays shallow, and the history says so once at the top, instead of letting every card look as though its stage produced nothing.

Forge dashboard (editor tab)

Command AISDLC: Open Forge Dashboard, or the dashboard icon on a forge row — the client row of the Forges view, above its tickets. Where the landing page shows the flow of one ticket, the dashboard shows the whole forge: every ticket container it has on this machine, with the state of each, the flow and role it runs, its branch, and how far it got in its flow (the same stage states as the landing page, as a bar).

Column What it shows
Ticket The Jira key, and the container name below it.
State The state as a colored dot: running, paused or ready.
Flow One segment per stage in execution order, colored from the ticket's status.
Branch The flow and role, the agent/<ticket> branch, and the start time of a running container.
The actions of the row: a terminal and stop for a running forge, resume for a paused one.

The ticket of the first column opens the landing page of a running forge, so the dashboard and the side bar lead to the same page from the row itself; a forge that is not up is started from the side bar, which knows its own state.

The page follows Docker: a forge that starts or stops moves its row without a click. Refresh re-reads the containers. A ticket that has no flow, or whose flow cannot be read, still shows its state — the row explains what is missing instead of hiding the ticket.

Forges (side bar)

Only what exists on this machine:

forge-acme                2 tickets
  ABC-12   dev
    Agent output          agents/tickets/ABC-12
    Repositories
      acme-backend        agent/ABC-12
  ABC-9    qa
forge-beta
  BETA-3   dev

Forge states: running, paused (stopped, kept). The row's icon and its actions carry the state — the description shows only the flow and role. Actions: start, open terminal, open in a new window (Dev Containers), show activity, stop, resume, discard, start another forge from the same client.

On a running forge the row carries, in this order:

  • a graph (AISDLC: Open Landing Page) — the flow of the ticket, its current stage and the reports each stage is expected to produce (see Landing page);
  • a terminal (AISDLC: Open Forge Terminal);
  • a red square (AISDLC: Stop Forge) — stops the container and keeps it, so the ticket can be resumed;
  • an X (AISDLC: Delete Forge and Container) — removes the container in one step, whether it runs or is stopped. The forge's base environment is shared with its other tickets, so it is always kept; nothing else is kept for a quick restart, but Discard states that explicitly.

A forge that is not running carries a green play (AISDLC: Start Forge) in the square's place — the two are never shown together, because a container is either running or not. The play resumes a paused container.

A client row (the forge itself) carries, besides its +, a dashboard (AISDLC: Open Forge Dashboard) — the overview of every ticket container of that client (see Forge dashboard) — and, once its base environment exists, a trash (AISDLC: Remove Base Environment) that drops it. The forge's tooltip names the base ref it is built from and its default branch; a forge created here is never silently rebuilt.

The play and square buttons are drawn as SVG icons of the extension (media/), one per theme, so they keep their color — green and red — instead of following the icon color of the theme. Both are outlined (no fill), 16×16, and cover the same area as the X.

Every container on the machine is simply listed; there is no "open here" marking, no per-window status-bar entry, and no notion of a forge being attached to the current window. The commands that take no row — Open in New Window, Open Forge Terminal Here — act on the only running forge, and ask which one when several are.

While a stop, a delete or a start is in flight, the row is greyed out with a spinner and offers no action, until Docker has settled — the play and Resume spin their row the same way Stop does. Such a row also cannot be expanded.

A running forge expands into:

  • Agent output: the flow folder of the session, /workspace/agents/tickets/<ticket>/<flow>, or the ticket folder /workspace/agents/tickets/<ticket>/ when the reports are there instead (a ticket prepared before the framework ran one folder per flow, or one whose flow folder is empty). Whichever it opens, it shows the reports of the agents only. They are the numbered .md files (00-ticket.md, 03-implementation.md, 05-review_failed-jobs_<repo>.md); research_report.md, index.yaml and the JSON settings around them stay hidden, and so does a folder that holds no report, dev/ and qa/ excepted when they carry their flow's reports.
  • Repositories: each clone under /workspace/repositories/, with branch and access.

Files open through the forge://<container>/<path> file system, run as agent_user. What can be edited, created, renamed or deleted is decided by that user's permissions in the container — the same permissions a terminal has; the extension adds no rule of its own. Paths outside /workspace are refused.

Forges started outside the extension (for example with the forge's docker compose setup) are listed too, and can be opened in a Dev Containers window from their row.

Deep links

Every page can be opened from a link, so a website, a Jira ticket or a wiki can carry an Open with AISDLC Companion button:

<a href="vscode://ComarchSA.aisdlc-companion/forge/acme/ABC-1">Open with AISDLC Companion</a>

The browser asks to open VS Code, the extension activates (onUri), the window is focused, and the page opens.

Link Page
vscode://ComarchSA.aisdlc-companion/ or /home Welcome / Overview
vscode://ComarchSA.aisdlc-companion/setup Setup; ?service=gitlab\|jira\|model\|registry focuses a card
vscode://ComarchSA.aisdlc-companion/new?client=acme&ticket=ABC-1 Start a Forge, with optional presets
vscode://ComarchSA.aisdlc-companion/forge or /forge/acme Forge dashboard (bare /forge asks which forge)
vscode://ComarchSA.aisdlc-companion/forge/acme/ABC-1 Landing page of a ticket

A client may be written acme, acme-forge or forge-acme; a ticket id is case-insensitive. A link to a forge or ticket that is not on this machine warns instead of opening an empty page, and an unknown link lists the supported forms.

The links carry no credentials and can open no destructive action: the reserved action parameter is an allowlist that is empty today, and any action added later must confirm inside VS Code before it does anything. Only a page is a link.

Settings

Setting Default Purpose
forge.docker.command ["docker"] Docker command, e.g. ["wsl", "docker"]
forge.localForges [] Local forge clones: name (<client>-forge) and path
forge.localForgeSearchRoots [] Folders scanned one level deep for local forge clones (a folder is a forge when it carries automated-flow/common/framework/setup-environment.sh and agents/repo-knowledge/)
forge.image.pipelineImage GitLab developer image FORGE_PIPELINE_IMAGE; empty keeps the extension Dockerfile default
forge.runtime.modelProvider factory FORGE_MODEL_PROVIDER; also set from the Setup page
forge.runtime.extraEnv [] Extra variable names forwarded to new forges
forge.container.user agent_user User for file access and terminals
forge.container.workspaceRoot /workspace Workspace root inside a forge
forge.refreshIntervalSeconds 15 Auto-refresh of the Forges view; 0 disables it
forge.workspace.exclude [".git"] Names hidden in forge files

GitLab and Jira URLs come from the Setup page, then GITLAB_BASE_URL / JIRA_BASE_URL, then the Comarch defaults.

Limitations

  • GitLab listing and fetching need network access to the GitLab host (VPN).
  • Text search across forge:// folders is not available (VS Code has no stable search API for custom file systems). Use a forge terminal or a Dev Container window.
  • With Docker inside WSL, the Dev Containers extension needs dev.containers.executeInWSL enabled to open a forge window.
  • Jira authentication uses a bearer personal access token (Jira Data Center).

Development

npm install
npm run typecheck
npm test                     # unit tests
FORGE_LIVE_CONTAINER=<name> npm test   # + live tests against a running forge
FORGE_LIVE_CONTAINER=<name> npm run smoke   # extension smoke test in an isolated VS Code
npm run bundle               # dist/extension.js
npm run package              # forge-<version>.vsix

Source layout: src/core/ holds pure logic with unit tests (no vscode import); src/ holds the VS Code layer; src/pages/ the editor-tab webviews (Welcome, Setup, Start a Forge, landing page, forge dashboard); src/views/ the Forges tree; docker/ the build recipe of every forge image.

Build recipe (docker/)

docker/Dockerfile, docker/forge-local-entrypoint.sh and docker/Dockerfile.dockerignore are the build recipe of a forge image. They are copied from the corresponding files of the forge repositories and must stay in sync with them — the stage whitelist of src/core/flows.ts mirrors the entrypoint's. docker/Dockerfile differs in one place: the entrypoint is taken from a second, named build context (--build-context forgeassets=<extension>/docker) instead of the forge clone, which is the main build context. The .dockerignore is named Dockerfile.dockerignore because Docker reads the ignore file of the context, and the context is the forge clone, not this folder.

The context is a checkout of the forge's default branch, and .git must stay in it: the entrypoint fetches and checks out the ticket's agent/<ticket> branch at container start, and flow and stage arrive as runtime env. The image therefore carries no ticket, flow or stage — one base image per forge, labelled com.aisdlc.forge.kind=base.

Page layout (final direction)

Every page is built with pageHtml() from src/pages/webviewKit.ts, and BASE_CSS in that file owns the shared look:

  • Background: the editor's own theme background (--vscode-editor-background), never a hardcoded color, so pages follow light and dark themes.
  • Layout: the page fills the editor it is opened in — no width cap and no centered column. The body padding (20px 28px 40px) is the only inset.

A new page must not restate either rule. It must not set its own body { max-width } or margin: 0 auto: the page uses all the space the editor gives it, and a page that wants to constrain what it draws constrains its own content (a ch-capped paragraph, a fixed-width chart card), never the page. All colors come from --vscode-* variables, so no page breaks under a theme switch.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft