deepdebug-local-agent 1.0.21 → 1.0.23

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/Dockerfile CHANGED
@@ -1,14 +1,14 @@
1
1
  # ╔══════════════════════════════════════════════════════════════╗
2
2
  # ║ DeepDebug Local Agent - Enterprise Docker ║
3
3
  # ║ ║
4
- # ║ Security-hardened container for enterprise deployments ║
4
+ # ║ Multi-language agent: Java, Node, Python, Go, Swift, Kotlin ║
5
5
  # ║ Supports: Cloud Run with NFS (GCP Filestore) ║
6
6
  # ╚══════════════════════════════════════════════════════════════╝
7
7
 
8
8
  # ===========================================
9
- # Stage 1: Build
9
+ # Stage 1: Build (Node dependencies)
10
10
  # ===========================================
11
- FROM node:20-alpine AS builder
11
+ FROM node:20-bookworm-slim AS builder
12
12
 
13
13
  WORKDIR /build
14
14
 
@@ -20,38 +20,73 @@ COPY src/ ./src/
20
20
  # ===========================================
21
21
  # Stage 2: Production
22
22
  # ===========================================
23
- FROM node:20-alpine AS production
23
+ FROM node:20-bookworm-slim AS production
24
24
 
25
25
  LABEL org.opencontainers.image.title="DeepDebug Local Agent"
26
26
  LABEL org.opencontainers.image.description="Enterprise debugging agent for code analysis"
27
27
  LABEL org.opencontainers.image.vendor="InspTech AI"
28
- LABEL org.opencontainers.image.version="1.2.0"
28
+ LABEL org.opencontainers.image.version="2.0.0"
29
29
  LABEL org.opencontainers.image.licenses="Proprietary"
30
30
  LABEL security.scan.required="true"
31
31
 
32
32
  # Create non-root user
33
- RUN addgroup -g 1001 -S deepdebug && \
34
- adduser -u 1001 -S deepdebug -G deepdebug
33
+ RUN groupadd -g 1001 deepdebug && \
34
+ useradd -u 1001 -g deepdebug -m deepdebug
35
35
 
36
- # Install dependencies including Java 17 for Maven wrapper support
37
- RUN apk update && \
38
- apk upgrade --no-cache && \
39
- apk add --no-cache \
36
+ # Install system dependencies: git, curl, Java 17, Maven, Python 3, NFS, dumb-init
37
+ RUN apt-get update && \
38
+ apt-get install -y --no-install-recommends \
40
39
  dumb-init \
41
40
  git \
42
41
  curl \
43
- nfs-utils \
44
- openjdk17-jdk \
42
+ wget \
43
+ ca-certificates \
44
+ nfs-common \
45
+ openjdk-17-jdk-headless \
45
46
  maven \
46
47
  python3 \
47
- && rm -rf /var/cache/apk/*
48
-
49
- # Set JAVA_HOME so ./mvnw can find Java
50
- # Alpine stores JVM under java-17-openjdk with arch suffix - use readlink to resolve
51
- RUN ln -sf $(dirname $(dirname $(readlink -f $(which java)))) /usr/local/java-home
52
- ENV JAVA_HOME=/usr/local/java-home
48
+ python3-pip \
49
+ binutils \
50
+ libc6-dev \
51
+ libcurl4-openssl-dev \
52
+ libedit2 \
53
+ libgcc-s1 \
54
+ libpython3.11 \
55
+ libsqlite3-0 \
56
+ libstdc++6 \
57
+ libxml2 \
58
+ libz3-4 \
59
+ pkg-config \
60
+ zlib1g-dev \
61
+ libncurses6 \
62
+ gcc \
63
+ g++ \
64
+ && rm -rf /var/lib/apt/lists/*
65
+
66
+ # Set JAVA_HOME
67
+ ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
53
68
  ENV PATH="$JAVA_HOME/bin:$PATH"
54
69
 
70
+ # ==========================================
71
+ # Install Swift 6.0.3 (Linux x86_64)
72
+ # This enables REAL compilation for iOS/Swift projects:
73
+ # - `swift build` for SPM projects
74
+ # - `swiftc -typecheck` for syntax validation of any .swift file
75
+ # - Full Foundation/Dispatch/XCTest on Linux
76
+ # ==========================================
77
+ ARG SWIFT_VERSION=5.10.1
78
+ RUN SWIFT_URL="https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz" && \
79
+ echo "Downloading Swift ${SWIFT_VERSION} for Ubuntu 22.04 (glibc compat with Bookworm)..." && \
80
+ wget -q "${SWIFT_URL}" -O /tmp/swift.tar.gz && \
81
+ mkdir -p /usr/share/swift && \
82
+ tar -xzf /tmp/swift.tar.gz -C /usr/share/swift --strip-components=2 && \
83
+ rm /tmp/swift.tar.gz && \
84
+ export PATH="/usr/share/swift/bin:$PATH" && \
85
+ swift --version && \
86
+ echo "Swift installed successfully"
87
+
88
+ ENV PATH="/usr/share/swift/bin:$PATH"
89
+
55
90
  # Create NFS mount point with correct ownership
56
91
  RUN mkdir -p /mnt/workspaces && \
57
92
  chown deepdebug:deepdebug /mnt/workspaces
@@ -89,4 +124,4 @@ ENV WORKSPACES_MOUNT=/mnt/workspaces
89
124
  EXPOSE 5055
90
125
 
91
126
  ENTRYPOINT ["dumb-init", "--"]
92
- CMD ["node", "src/server.js"]
127
+ CMD ["node", "src/server.js"]
package/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # DeepDebug Local Agent
2
+
3
+ AI-powered on-prem ingestion arm of the VisionHammer / DeepDebug pipeline. The
4
+ local agent watches application logs, surfaces incidents, and forwards them to
5
+ the gateway for downstream analysis.
6
+
7
+ - **Runtime:** Node.js 18+ (pure ESM, `"type": "module"`)
8
+ - **Test runner:** `node:test` (Node built-in)
9
+ - **Distribution:** `npm install` for development; `pkg`-bundled binaries for
10
+ production install (`npm run build:all`)
11
+ - **Package:** `deepdebug-local-agent@1.0.21`
12
+
13
+ ## Quick start
14
+
15
+ ```bash
16
+ npm install
17
+ npm test # runs node --test (52 tests across adapters + registry)
18
+ npm start # boots the agent (default port 5055; MCP bridge on 5056)
19
+ ```
20
+
21
+ Configuration lives in `~/.deepdebug/config.json` and via env vars (`PORT`,
22
+ `MCP_PORT`, `GATEWAY_URL`, `DEEPDEBUG_API_KEY`, `TENANT_ID`,
23
+ `DISABLE_WS_TUNNEL`, `LEGACY_STACKS`).
24
+
25
+ Companion docs:
26
+
27
+ - [QUICKSTART.md](./docs/QUICKSTART.md) — end-user install + first-run
28
+ - [ENTERPRISE_DEPLOYMENT_GUIDE.md](./docs/ENTERPRISE_DEPLOYMENT_GUIDE.md)
29
+ - [SECURITY_WHITEPAPER.md](./docs/SECURITY_WHITEPAPER.md)
30
+ - [docs/legacy-connectors.md](./docs/legacy-connectors.md) — **Phase 2** legacy
31
+ stack ingestion reference
32
+
33
+ ## Features
34
+
35
+ - Real-time application log ingestion via `processManager.on('log', ...)`
36
+ - AI-driven patch generation (`AIVibeCodingEngine`) wired to the gateway
37
+ - Workspace-scoped operations via the workspace manager
38
+ - Backup / restore with disk-indexed history
39
+ - WebSocket reverse tunnel to the gateway (`startWebSocketTunnel`)
40
+ - MCP HTTP bridge (`startMCPHttpServer` on port 5056)
41
+ - **Legacy connectors** — five EventEmitter adapters for legacy on-prem stacks
42
+ (see below)
43
+
44
+ ## Legacy connectors
45
+
46
+ DeepDebug Local Agent ships five EventEmitter adapters for legacy on-prem
47
+ stacks, behind a single `LEGACY_STACKS` env var:
48
+
49
+ - **SAP** (`src/adapters/sap/`) — watches SAP NetWeaver `dev_w*` work-process
50
+ traces + `SLOG*` system logs
51
+ - **IBM MQ** (`src/adapters/ibmmq/`) — watches `AMQERR0[1-3].LOG` files
52
+ - **AS/400** (`src/adapters/as400/`) — polls DSPLOG via SSH with auto-reconnect
53
+ - **Oracle Forms** (`src/adapters/oracle-forms/`) — watches `*.trc` trace files
54
+ (Latin-1 tolerant)
55
+ - **COBOL/Mainframe** (`src/adapters/cobol/`) — watches JES2 spool exports
56
+ (CRLF + 80-col tolerant)
57
+
58
+ Each adapter emits `error` events with a frozen 6-key shape:
59
+ `{adapter, errorCode, file, message, source, timestamp}`.
60
+
61
+ To enable: set `LEGACY_STACKS=sap,cobol` (comma-separated subset of
62
+ `sap,ibmmq,as400,oracle-forms,cobol`) in the agent's environment. When unset,
63
+ the adapters are not loaded and the local-agent boot path is byte-for-byte
64
+ unchanged.
65
+
66
+ Full configuration + troubleshooting reference:
67
+ [docs/legacy-connectors.md](./docs/legacy-connectors.md).
68
+
69
+ ## Development
70
+
71
+ ```bash
72
+ npm test # full suite (52 tests)
73
+ npm run sync-fixtures # refresh test/fixtures/<stack>/ from example repos
74
+ # (requires ~/.config/visionhammer/github-pat)
75
+ npm run lint # eslint src/
76
+ npm run dev # NODE_ENV=development node src/server.js
77
+ ```
78
+
79
+ ## License
80
+
81
+ Proprietary — InspTech AI.
@@ -0,0 +1,40 @@
1
+ steps:
2
+ - name: 'gcr.io/cloud-builders/docker'
3
+ args:
4
+ - 'build'
5
+ - '--platform=linux/amd64'
6
+ - '-t'
7
+ - 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-staging:latest'
8
+ - '.'
9
+ timeout: '600s'
10
+
11
+ - name: 'gcr.io/cloud-builders/docker'
12
+ args:
13
+ - 'push'
14
+ - 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-staging:latest'
15
+
16
+ - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
17
+ entrypoint: 'gcloud'
18
+ args:
19
+ - 'run'
20
+ - 'deploy'
21
+ - 'deepdebug-local-agent-staging'
22
+ - '--image=us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-staging:latest'
23
+ - '--region=us-central1'
24
+ - '--platform=managed'
25
+ - '--allow-unauthenticated'
26
+ - '--memory=1Gi'
27
+ - '--cpu=1'
28
+ - '--min-instances=1'
29
+ - '--max-instances=3'
30
+ - '--port=5055'
31
+ - '--timeout=300'
32
+ - '--update-env-vars=NODE_ENV=staging'
33
+
34
+ images:
35
+ - 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-staging:latest'
36
+
37
+ options:
38
+ logging: CLOUD_LOGGING_ONLY
39
+
40
+ timeout: '1200s'
@@ -0,0 +1,268 @@
1
+ # Legacy connectors — configuration & troubleshooting
2
+
3
+ Phase 2 of VisionHammer ships five Node.js EventEmitter adapters that ingest
4
+ logs from legacy on-prem systems into the DeepDebug pipeline. This document is
5
+ the operator's reference for enabling and tuning them.
6
+
7
+ ## Quick start
8
+
9
+ 1. Read [Setup](#setup) to configure your GitHub PAT (only needed if you plan to
10
+ run `npm run sync-fixtures` to refresh test fixtures).
11
+ 2. Set `LEGACY_STACKS=<stacks>` in the agent's environment to choose which
12
+ adapters boot. Example: `LEGACY_STACKS=sap,cobol`.
13
+ 3. Provide per-adapter config via env or `agent.yaml` (see
14
+ [Configuration](#configuration) below).
15
+ 4. Restart the local agent. Adapters start automatically and stop within 5 s on
16
+ `SIGTERM`.
17
+
18
+ ## Setup
19
+
20
+ The `npm run sync-fixtures` script clones the
21
+ `williambella/visionhammer-example-*` GitHub repos to refresh
22
+ `test/fixtures/<stack>/` from upstream. It needs a GitHub PAT.
23
+
24
+ 1. On github.com → Developer settings → Personal access tokens → Tokens
25
+ (classic) → Generate new token. Scope: `repo` (read-only is sufficient).
26
+ 2. Save the PAT to `~/.config/visionhammer/github-pat` with permissions `0600`:
27
+ ```bash
28
+ mkdir -p ~/.config/visionhammer
29
+ echo "YOUR_PAT_HERE" > ~/.config/visionhammer/github-pat
30
+ chmod 600 ~/.config/visionhammer/github-pat
31
+ ```
32
+ 3. **Never paste** the PAT into a shell env var. The script reads the file
33
+ directly at invocation time and validates the token against `GET /user`
34
+ before any clone. (T-2-04 + T-2-05 mitigation.)
35
+
36
+ ## Configuration
37
+
38
+ Adapters are configured via the `LEGACY_STACKS` env var (which stacks to boot)
39
+ plus per-adapter env vars or `agent.yaml` entries.
40
+
41
+ ### Supported stacks
42
+
43
+ | Stack | Adapter dir | Default config | Required mounts/access |
44
+ | -------------- | -------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
45
+ | `sap` | `src/adapters/sap/` | `{sapDir: '/usr/sap/PRD', instanceNumber: '00', interval: 5000}` | NFS/SMB mount of `/usr/sap/<SID>/` readable by the agent user |
46
+ | `ibmmq` | `src/adapters/ibmmq/` | `{errorsDir: '/var/mqm/qmgrs/QM_PRD01/errors', interval: 5000}` | Read access to qmgr `errors/` directory |
47
+ | `as400` | `src/adapters/as400/` | `{host: 'as400-prd-01', port: 22, pollInterval: 30000}` | SSH credentials (password OR private-key); user with `DSPLOG` authority |
48
+ | `oracle-forms` | `src/adapters/oracle-forms/` | `{traceDir: '/u01/oracle/forms/trace', interval: 5000}` | Read access to `FORMS_TRACE_DIR` |
49
+ | `cobol` | `src/adapters/cobol/` | `{spoolDir: '/var/spool/jes2', interval: 5000}` | Read access to JES2 spool export dir |
50
+
51
+ Glob anchors (per-adapter, hard-coded):
52
+
53
+ - **SAP** watches `<sapDir>/D<instanceNumber>/work/dev_w*` AND
54
+ `<sapDir>/D<instanceNumber>/log/SLOG*` (T-2-03 mitigation — narrow regex
55
+ surface).
56
+ - **IBM MQ** watches `<errorsDir>/AMQERR*.LOG` then enforces filename anchor
57
+ `^AMQERR0[1-3]\.LOG$` in-handler (chokidar bracket-class workaround on macOS
58
+ / Node 24 / chokidar 3.6.0).
59
+ - **Oracle Forms** watches `<traceDir>/*.trc` only (`*.log` is **not** read).
60
+ - **COBOL** watches `<spoolDir>/*` with `depth: 0` (broad spool glob — JES2
61
+ exports use arbitrary file names; non-files are filtered with `isFile()`).
62
+ - **AS/400** does NOT watch files; it polls the literal command
63
+ `system "DSPLOG OUTPUT(*PRINT) LOGTYPE(*MSG) MSGTYPE(*ESCAPE *NOTIFY)"` over
64
+ SSH every `pollInterval` ms.
65
+
66
+ ### Per-adapter config sub-objects
67
+
68
+ The registry's
69
+ `loadAdapters({legacyStacks, sap, ibmmq, as400, 'oracle-forms', cobol})`
70
+ accepts one sub-object per stack. Each is passed straight to the adapter
71
+ constructor. Override defaults by setting the corresponding key. Example:
72
+
73
+ ```javascript
74
+ import { loadAdapters, stopAll } from "./src/adapters/index.js";
75
+
76
+ const adapters = loadAdapters({
77
+ legacyStacks: ['sap', 'cobol'],
78
+ sap: { sapDir: '/sapmnt/PRD', instanceNumber: '01', interval: 10000 },
79
+ cobol: { spoolDir: '/mnt/zos/spool', interval: 30000 },
80
+ });
81
+
82
+ for (const a of adapters) await a.start();
83
+ // ... later, on shutdown
84
+ await stopAll(adapters, 5000);
85
+ ```
86
+
87
+ `loadAdapters` returns adapters **unstarted** (AD-1 contract). The caller owns
88
+ the lifecycle. The `LEGACY_STACKS` env-var bootstrap path in `src/server.js`
89
+ already wires `loadAdapters` + `start()` for you when the env var is set.
90
+
91
+ ## Event shape
92
+
93
+ Every adapter emits `error` events with EXACTLY this shape (frozen, 6 keys, no
94
+ extras — alphabetical key order matters for the failsafe contract test):
95
+
96
+ ```javascript
97
+ {
98
+ adapter: 'sap' | 'ibmmq' | 'as400' | 'oracle-forms' | 'cobol',
99
+ errorCode: 'ORA-01403' | 'AMQ7472W' | 'CPF1234' | 'S0C7' | null,
100
+ file: '/usr/sap/PRD/D00/work/dev_w0',
101
+ message: '<verbatim matched line>',
102
+ source: '/usr/sap/PRD/D00/work',
103
+ timestamp: '2024-01-15T09:12:44.000Z'
104
+ }
105
+ ```
106
+
107
+ Per AD-5, events are ordered by byte position **within a single file**.
108
+ Cross-file and cross-adapter ordering are explicit non-guarantees — the
109
+ downstream gateway pipeline correlates by `incidentId`, not by event sequence.
110
+
111
+ `timestamp` is the moment the adapter detected the line (not the timestamp
112
+ inside the log line — log-line timestamps have inconsistent precision across
113
+ formats).
114
+
115
+ ## Sync fixtures script
116
+
117
+ ```bash
118
+ # Sync all 5 stacks
119
+ npm run sync-fixtures
120
+
121
+ # Sync only a subset
122
+ node scripts/sync-fixtures.mjs --stacks=oracle-forms,cobol
123
+ ```
124
+
125
+ What it does, in order, for each requested stack:
126
+
127
+ 1. Reads the PAT once from `~/.config/visionhammer/github-pat`.
128
+ 2. Validates the PAT via `GET https://api.github.com/user` (T-2-05).
129
+ 3. Shallow-clones `williambella/visionhammer-example-<stack>` to
130
+ `/tmp/sync-<stack>` via `git clone --depth 1 --branch main` with the PAT
131
+ embedded in the URL **only as a `child_process.spawn` argv element**, never
132
+ echoed to stdout/stderr/argv-string/env (T-2-04).
133
+ 4. Copies `samples/*.log` (case-insensitive) into `test/fixtures/<dir>/`
134
+ (mapping: `sap-abap → sap`, `ibm-mq → ibmmq`, others identity).
135
+ 5. Renames IBM MQ fixtures so they pass the adapter's `^AMQERR0[1-3]\.LOG$`
136
+ filename anchor:
137
+
138
+ | Source filename | Target filename |
139
+ | ---------------------------------------- | --------------- |
140
+ | `ibm-mq-sample-mqrc-2033.log` | `AMQERR01.LOG` |
141
+ | `ibm-mq-sample-mqrc-2058.log` | `AMQERR02.LOG` |
142
+ | `ibm-mq-sample-resource-leak.log` | `AMQERR03.LOG` |
143
+
144
+ 6. Removes the `/tmp/sync-<stack>` clone scratch dir.
145
+
146
+ Idempotent — re-runs cleanly overwrite prior fixtures and rewipe scratch dirs.
147
+ On git failure the embedded PAT is replaced with `***REDACTED***` before
148
+ stderr is written.
149
+
150
+ ## Example fixture repos
151
+
152
+ | Stack | Repo |
153
+ | ----------------- | ------------------------------------------------------------------------------------------ |
154
+ | Oracle Forms 12c | [williambella/visionhammer-example-oracle-forms](https://github.com/williambella/visionhammer-example-oracle-forms) |
155
+ | Oracle PL/SQL | [williambella/visionhammer-example-plsql](https://github.com/williambella/visionhammer-example-plsql) |
156
+ | SAP ABAP | [williambella/visionhammer-example-sap-abap](https://github.com/williambella/visionhammer-example-sap-abap) |
157
+ | COBOL / z/OS | [williambella/visionhammer-example-cobol](https://github.com/williambella/visionhammer-example-cobol) |
158
+ | IBM MQ Java | [williambella/visionhammer-example-ibm-mq](https://github.com/williambella/visionhammer-example-ibm-mq) |
159
+
160
+ Each repo carries: an intentional-bug `README.md`, source code reproducing each
161
+ bug, `samples/<stack>-sample-<n>.log` synthetic logs, and `samples/README.md`
162
+ with `## Source citation`, `## Product version`, and
163
+ `## Zero PII confirmation` sections per AD-6.
164
+
165
+ ## Troubleshooting
166
+
167
+ ### CPU usage too high (T-2-01)
168
+
169
+ Default poll intervals are conservative (5 s for chokidar-based adapters,
170
+ 30 s for AS/400 SSH). If you see elevated CPU on the agent host or the legacy
171
+ system:
172
+
173
+ - Increase `interval` for chokidar adapters (sap, ibmmq, oracle-forms, cobol).
174
+ Try `10000` (10 s) first.
175
+ - Increase `pollInterval` for AS/400. Try `60000` (60 s).
176
+ - Do **not** set `interval < 1000`. NFS/SMB watch polling at sub-second cadence
177
+ is pathological for production systems.
178
+
179
+ ### AS/400 SSH session keeps dropping (T-2-02)
180
+
181
+ The AS/400 adapter uses SSH keepalive (`keepaliveInterval: 30000` ×
182
+ `keepaliveCountMax: 3` = 90 s tolerance) and auto-reconnects on `'close'` with
183
+ exponential backoff:
184
+
185
+ ```
186
+ 1 s → 2 s → 4 s → 8 s → 16 s → 32 s → 60 s (cap)
187
+ ```
188
+
189
+ Backoff resets to 1 s on successful re-auth (`'ready'` event).
190
+
191
+ To verify reconnect health: tail the agent log; `'close'` events should be
192
+ followed by a successful `'ready'` within ~60 s. If reconnect storms occur:
193
+
194
+ - Verify the AS/400 SSH server's idle timeout setting. Some SSH daemons close
195
+ sessions despite keepalive; tune the daemon's `ClientAliveInterval` higher
196
+ than 30 s.
197
+ - Check network MTU between the agent and AS/400. Fragmented keepalive packets
198
+ get dropped.
199
+ - The polling cadence (`pollInterval`, default 30 s) is independent of the
200
+ keepalive cadence — they run on separate timers.
201
+
202
+ ### `npm run sync-fixtures` fails with "GitHub credentials not configured"
203
+
204
+ Confirm `~/.config/visionhammer/github-pat` exists, is readable by the agent
205
+ user, and contains a valid PAT with `repo` scope. The script reads this file
206
+ once at invocation; it never accepts a PAT from env vars. (T-2-04 mitigation.)
207
+
208
+ ### `npm run sync-fixtures` fails with "PAT validation failed"
209
+
210
+ The PAT validity gate (`GET /user`) returned a non-200 status. Causes:
211
+
212
+ - PAT expired or revoked. Regenerate at github.com/settings/tokens.
213
+ - PAT lost `repo` scope. Regenerate.
214
+ - Network failure to api.github.com. Re-run when connectivity returns.
215
+
216
+ ### `npm run sync-fixtures` partial failure for one stack
217
+
218
+ The script aborts on first failure (per current implementation) so each clone
219
+ gates the next. Common causes:
220
+
221
+ - Repo deleted from `williambella/visionhammer-example-<stack>`. Recreate by
222
+ re-running Phase 2 / Plan 02-0X (where X = 2..6).
223
+ - Stack name typo in `--stacks=`. Allowed values:
224
+ `oracle-forms,plsql,sap-abap,cobol,ibm-mq`.
225
+ - Network failure mid-clone. Re-run the script.
226
+
227
+ ### SIGTERM doesn't shut down adapters cleanly
228
+
229
+ The `SIGTERM` handler in `src/server.js` calls `stopAll(_legacyAdapters, 5000)`
230
+ — adapters have 5 s to release file handles + close SSH. The 5-s budget is
231
+ enforced by an `unref`'d timer racing the `Promise.all` of per-adapter
232
+ `stop()` calls; per-adapter exceptions are swallowed so the shutdown path
233
+ always returns.
234
+
235
+ If a process refuses to exit altogether, that's a separate concern: the
236
+ `local-agent` process keeps an `express` listener (`PORT`) and an MCP HTTP
237
+ listener (`MCP_PORT`) open, plus an optional WebSocket reverse tunnel. Those
238
+ are not closed by the SIGTERM handler today (pre-existing local-agent
239
+ architecture). Set `DISABLE_WS_TUNNEL=true` to drop the WS half; the express
240
+ + MCP listeners require a separate explicit close path.
241
+
242
+ For the **legacy connector contract specifically** — `stopAll(adapters, 5000)`
243
+ is verified to resolve within 5 s (registry contract test
244
+ `stopAll respects timeout — slow stop does not block forever`).
245
+
246
+ ### Adapter logs nothing
247
+
248
+ Possible causes by adapter:
249
+
250
+ - **All chokidar adapters** — TAIL mode is the default. Newly-appended lines
251
+ emit; existing content does not. To replay a file from byte 0 set
252
+ `replayOnStart: true` in the adapter config.
253
+ - **SAP / IBM MQ / Oracle Forms / COBOL** — verify the watched directory
254
+ exists; ENOENT is silent by design (legitimate state for newly-provisioned
255
+ systems).
256
+ - **IBM MQ** — only `AMQERR01.LOG`, `AMQERR02.LOG`, `AMQERR03.LOG` are read.
257
+ `AMQERR04.LOG` and other names are silently dropped at the in-handler anchor
258
+ regex.
259
+ - **AS/400** — verify SSH connectivity (`ssh -p 22 user@as400-prd-01 'system DSPLOG'`).
260
+ ENOENT-equivalent (unreachable host) shows in the agent stderr only on the
261
+ first `'close'` failure; subsequent reconnect attempts are silent.
262
+
263
+ ## Field references
264
+
265
+ - 02-SPEC.md: `~/Documents/Projects/visionhammer-agents/.planning/phases/02-legacy-stack-support/02-SPEC.md`
266
+ - Phase 3 (LegacyErrorPatterns Java catalog): consumes `test/fixtures/<stack>/`
267
+ as test fixtures.
268
+ - Phase 6 (E2E smoke): re-uses the example repos as workspaces.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepdebug-local-agent",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "DeepDebug Local Agent - AI-powered code debugging assistant",
5
5
  "private": false,
6
6
  "type": "module",
@@ -22,6 +22,7 @@
22
22
  "docker:build": "docker build -t deepdebug/local-agent:latest .",
23
23
  "docker:push": "docker push deepdebug/local-agent:latest",
24
24
  "test": "node --test",
25
+ "sync-fixtures": "node scripts/sync-fixtures.mjs",
25
26
  "lint": "eslint src/"
26
27
  },
27
28
  "pkg": {
@@ -34,12 +35,14 @@
34
35
  "@anthropic-ai/sdk": "^0.39.0",
35
36
  "@modelcontextprotocol/sdk": "^1.0.4",
36
37
  "body-parser": "^1.20.3",
38
+ "chokidar": "^3.6.0",
37
39
  "cors": "^2.8.5",
38
40
  "express": "^4.19.2",
39
41
  "js-yaml": "^4.1.0",
40
42
  "pg": "^8.20.0",
41
43
  "pidusage": "^3.0.2",
42
44
  "properties-reader": "^2.3.0",
45
+ "ssh2": "^1.16.0",
43
46
  "strip-ansi": "^7.1.0",
44
47
  "unidiff": "^1.0.2",
45
48
  "ws": "^8.18.0"