deepdebug-local-agent 1.0.22 → 1.1.0
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/.claude/context.md +76 -0
- package/.claude/skills/README.md +25 -0
- package/.claude/skills/tdd-debugging/SKILL.md +53 -0
- package/.claude/skills/tdd-debugging/references/anti-patterns.md +43 -0
- package/.claude/skills/tdd-debugging/references/command-reference.md +46 -0
- package/.claude/standards/README.md +51 -0
- package/.claude/standards/clean-code.md +75 -0
- package/.claude/standards/code-review-checklist.md +61 -0
- package/.claude/standards/layered-architecture.md +163 -0
- package/.claude/standards/node.md +45 -0
- package/.claude/standards/security-owasp.md +114 -0
- package/.claude/standards/simplicity.md +42 -0
- package/.claude/standards/solid.md +64 -0
- package/.claude/standards/testing.md +59 -0
- package/.cursor/rules/standards.mdc +17 -0
- package/.github/workflows/build-byoc-image.yml +315 -0
- package/.github/workflows/deploy-gcp.yml +102 -0
- package/.github/workflows/npm-publish.yml +69 -8
- package/AGENTS.md +21 -0
- package/CHANGELOG.md +69 -0
- package/CLAUDE.md +13 -0
- package/CLAUDE_CODE_AGENT_INFINITE.md +5 -3
- package/Dockerfile +4 -0
- package/Dockerfile.full +55 -3
- package/README.md +81 -0
- package/bin/install.js +16 -5
- package/cloudbuild-full.yaml +57 -0
- package/docker-compose.yml +5 -3
- package/docs/OBSERVABILITY.md +164 -0
- package/docs/byoc-agent-image.md +70 -0
- package/docs/graphify-packaging-plan.md +133 -0
- package/docs/graphify-validation-run-2026-10-28.md +243 -0
- package/docs/legacy-connectors.md +268 -0
- package/docs/releasing.md +43 -0
- package/docs/signed-commands.md +163 -0
- package/env.example +30 -0
- package/helm/Chart.yaml +2 -2
- package/helm/templates/deployment.yaml +13 -3
- package/helm/templates/networkpolicy.yaml +22 -0
- package/helm/templates/secret.yaml +1 -0
- package/helm/values.yaml +13 -14
- package/mcp-server.js +4 -1
- package/package.json +12 -4
- package/scripts/sync-fixtures.mjs +246 -0
- package/scripts/upgrade-observability-push.sh +227 -0
- package/src/adapters/as400/as400-parser.js +12 -0
- package/src/adapters/as400/index.js +134 -0
- package/src/adapters/cobol/cobol-parser.js +37 -0
- package/src/adapters/cobol/index.js +151 -0
- package/src/adapters/ibmmq/ibmmq-parser.js +23 -0
- package/src/adapters/ibmmq/index.js +137 -0
- package/src/adapters/index.js +79 -0
- package/src/adapters/oracle-forms/index.js +145 -0
- package/src/adapters/oracle-forms/oracle-forms-parser.js +11 -0
- package/src/adapters/sap/index.js +146 -0
- package/src/adapters/sap/sap-parser.js +41 -0
- package/src/ai-engine.js +22 -22
- package/src/config/trusted-signing-keys.json +3 -0
- package/src/detectors/build-tool-detector.js +50 -0
- package/src/detectors/multi-project-detector.js +22 -22
- package/src/detectors/service-detector.js +24 -24
- package/src/exec-utils.js +26 -4
- package/src/git/base-git-provider.js +117 -117
- package/src/git/bitbucket-provider.js +2 -2
- package/src/git/git-provider-registry.js +18 -18
- package/src/git/github-provider.js +13 -13
- package/src/git/multi-repo-pr.js +161 -0
- package/src/mcp-http-server.js +32 -16
- package/src/observability/bundle-files.js +418 -0
- package/src/observability/detect.js +151 -0
- package/src/observability/provision.js +212 -0
- package/src/observability/render-cli.js +59 -0
- package/src/observability/routes.js +88 -0
- package/src/patch/patch-engine.js +28 -28
- package/src/patch-manager.js +85 -85
- package/src/patch_bkp.js +14 -14
- package/src/ports.js +4 -4
- package/src/routes/workspace.route.js +47 -16
- package/src/runtimes/base-runtime.js +75 -75
- package/src/runtimes/java/gradle-runtime.js +17 -17
- package/src/runtimes/java/java-integrations.js +25 -25
- package/src/runtimes/java/maven-runtime.js +34 -34
- package/src/runtimes/node/node-integrations.js +1 -1
- package/src/runtimes/node/npm-runtime.js +14 -14
- package/src/runtimes/node/yarn-runtime.js +4 -4
- package/src/runtimes/runtime-registry.js +25 -25
- package/src/server-local.js +4 -4
- package/src/server.js +1412 -335
- package/src/siblings/burst-suppressor.js +89 -0
- package/src/siblings/capabilities.js +273 -0
- package/src/siblings/env-compat.cjs +58 -0
- package/src/siblings/incident-forwarder.js +320 -0
- package/src/siblings/logger.js +15 -0
- package/src/siblings/metrics.js +94 -0
- package/src/utils/agent-auth.js +184 -0
- package/src/utils/approval-token.js +56 -0
- package/src/utils/bind-host.js +29 -0
- package/src/utils/branch-refspec.js +98 -0
- package/src/utils/child-env.js +34 -0
- package/src/utils/environment-diagnostics.js +55 -55
- package/src/utils/exec-policy.js +962 -0
- package/src/utils/exec-utils.js +15 -15
- package/src/utils/file-count.js +46 -0
- package/src/utils/fs-utils.js +10 -10
- package/src/utils/multi-repo-open.js +132 -0
- package/src/utils/open-gate.js +183 -0
- package/src/utils/ranged-read.js +65 -0
- package/src/utils/request-guards.js +77 -0
- package/src/utils/request-signing.js +342 -0
- package/src/utils/root-recovery.js +244 -0
- package/src/utils/safe-exec-args.js +58 -0
- package/src/utils/sandbox.js +182 -0
- package/src/utils/search-outcome.js +56 -0
- package/src/utils/workspace-root.js +80 -0
- package/src/validators/syntax-validator.js +149 -0
- package/src/workspace/detect-port.js +16 -16
- package/src/workspace/file-reader.js +1 -1
- package/src/workspace/process-manager.js +46 -46
- package/src/workspace-manager.js +86 -24
- package/test/adapters/as400/as400.test.js +121 -0
- package/test/adapters/cobol/cobol.test.js +217 -0
- package/test/adapters/ibmmq/ibmmq.test.js +122 -0
- package/test/adapters/oracle-forms/oracle-forms.test.js +180 -0
- package/test/adapters/registry.test.js +108 -0
- package/test/adapters/sap/sap.test.js +142 -0
- package/test/agent-auth.test.js +194 -0
- package/test/bind-host.test.js +26 -0
- package/test/branch-refspec.test.js +224 -0
- package/test/burst-suppressor.test.js +60 -0
- package/test/capabilities-access.test.js +47 -0
- package/test/capabilities.test.js +87 -0
- package/test/child-env.test.js +23 -0
- package/test/env-compat.test.js +71 -0
- package/test/exec-policy.test.js +463 -0
- package/test/file-count.test.js +64 -0
- package/test/incident-forwarder.test.js +231 -0
- package/test/multi-repo-open.test.js +180 -0
- package/test/multi-repo-pr.test.js +129 -0
- package/test/observability-detect.test.js +199 -0
- package/test/open-gate.test.js +341 -0
- package/test/ranged-read.test.js +60 -0
- package/test/request-guards.test.js +91 -0
- package/test/request-signing.test.js +284 -0
- package/test/root-recovery-sidecar.test.js +171 -0
- package/test/root-recovery.test.js +274 -0
- package/test/safe-exec-args.test.js +58 -0
- package/test/sandbox.test.js +98 -0
- package/test/search-outcome.test.js +50 -0
- package/test/workspace-root.test.js +64 -0
- package/tools/graphify-validation/README.md +92 -0
- package/tools/graphify-validation/config/questions.json +31 -0
- package/tools/graphify-validation/config/repos.json +9 -0
- package/tools/graphify-validation/config/symbols.json +6 -0
- package/tools/graphify-validation/fixtures/spring/expected.json +34 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/AppConfig.java +29 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/AuditLogger.java +15 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/Cache.java +7 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/CheckoutService.java +25 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/InMemoryCache.java +18 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/OrderController.java +22 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/PaymentGateway.java +5 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/PaypalGateway.java +11 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/RefundService.java +14 -0
- package/tools/graphify-validation/fixtures/spring/src/main/java/com/example/fx/StripeGateway.java +11 -0
- package/tools/graphify-validation/lib/affected_vs_rg.py +81 -0
- package/tools/graphify-validation/lib/audit_hook/sitecustomize.py +22 -0
- package/tools/graphify-validation/lib/graph_metrics.py +96 -0
- package/tools/graphify-validation/lib/gv_common.py +130 -0
- package/tools/graphify-validation/lib/licenses.py +47 -0
- package/tools/graphify-validation/lib/pip_audit_summary.py +18 -0
- package/tools/graphify-validation/lib/recall.py +115 -0
- package/tools/graphify-validation/lib/report.py +226 -0
- package/tools/graphify-validation/lib/run_all.py +237 -0
- package/tools/graphify-validation/lib/run_graphify.py +144 -0
- package/tools/graphify-validation/lib/rusage_helper.py +17 -0
- package/tools/graphify-validation/lib/sample_edges.py +246 -0
- package/tools/graphify-validation/lib/spring_fixture.py +81 -0
- package/tools/graphify-validation/requirements-py311.lock +508 -0
- package/tools/graphify-validation/requirements-tools.in +1 -0
- package/tools/graphify-validation/requirements-tools.lock +371 -0
- package/tools/graphify-validation/requirements.in +1 -0
- package/tools/graphify-validation/requirements.lock +502 -0
- package/tools/graphify-validation/run.sh +43 -0
- package/tools/graphify-validation/tests/test_harness.py +151 -0
- package/cloudbuild-agent-qa.yaml +0 -43
- package/cloudbuild-agent-staging.yaml +0 -40
- package/cloudbuild.yaml.deprecated +0 -42
- package/src/local-agent-source.tar.gz +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Deploy local-agent (Node) to GCP Cloud Run (visionhammer) via WIF.
|
|
2
|
+
# Manual-only: this repo has no develop branch and several active feature
|
|
3
|
+
# branches, so deploys are triggered on demand from the Actions tab. Choose the
|
|
4
|
+
# environment input. Replaces the insptechai Cloud Build path.
|
|
5
|
+
name: Deploy Local Agent to GCP
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
environment:
|
|
11
|
+
description: 'Target environment'
|
|
12
|
+
required: true
|
|
13
|
+
default: 'qa'
|
|
14
|
+
type: choice
|
|
15
|
+
options: [qa, prod]
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: deploy-local-agent-${{ github.ref }}-${{ inputs.environment }}
|
|
19
|
+
cancel-in-progress: true
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
id-token: write
|
|
24
|
+
|
|
25
|
+
env:
|
|
26
|
+
GCP_PROJECT: visionhammer
|
|
27
|
+
# EU migration (PLANO-MIGRACAO-EU-PROD.md): PROD moves to europe-west1. The
|
|
28
|
+
# region comes from repo variables (PROD_REGION / QA_REGION); today's value
|
|
29
|
+
# stays the default, so nothing changes until the variable is set.
|
|
30
|
+
GCP_REGION: ${{ inputs.environment == 'prod' && (vars.PROD_REGION || 'us-central1') || (vars.QA_REGION || 'us-central1') }}
|
|
31
|
+
WIF_PROVIDER: projects/1009366917257/locations/global/workloadIdentityPools/github-pool/providers/github-provider
|
|
32
|
+
DEPLOYER_SA: github-deployer@visionhammer.iam.gserviceaccount.com
|
|
33
|
+
AR_IMAGE: us-central1-docker.pkg.dev/visionhammer/visionhammer-docker/local-agent
|
|
34
|
+
|
|
35
|
+
jobs:
|
|
36
|
+
deploy:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment: ${{ inputs.environment == 'prod' && 'production' || 'qa' }}
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
- name: Resolve target (service + tag)
|
|
43
|
+
id: vars
|
|
44
|
+
run: |
|
|
45
|
+
if [ "${{ inputs.environment }}" = "prod" ]; then
|
|
46
|
+
# PROD only from main: a dispatch from a feature branch must not
|
|
47
|
+
# reach production (QA may still deploy any branch on purpose).
|
|
48
|
+
if [ "${GITHUB_REF}" != "refs/heads/main" ]; then
|
|
49
|
+
echo "::error::PROD deploys only from main (got ${GITHUB_REF})."
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
echo "service=deepdebug-local-agent" >> "$GITHUB_OUTPUT"
|
|
53
|
+
echo "tag=prod-${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT"
|
|
54
|
+
echo "traffic=canary" >> "$GITHUB_OUTPUT"
|
|
55
|
+
else
|
|
56
|
+
echo "service=deepdebug-local-agent-qa" >> "$GITHUB_OUTPUT"
|
|
57
|
+
echo "tag=qa-${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT"
|
|
58
|
+
echo "traffic=live" >> "$GITHUB_OUTPUT"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
- name: Authenticate to GCP (WIF)
|
|
62
|
+
uses: google-github-actions/auth@v2
|
|
63
|
+
with:
|
|
64
|
+
workload_identity_provider: ${{ env.WIF_PROVIDER }}
|
|
65
|
+
service_account: ${{ env.DEPLOYER_SA }}
|
|
66
|
+
|
|
67
|
+
- name: Set up gcloud
|
|
68
|
+
uses: google-github-actions/setup-gcloud@v2
|
|
69
|
+
|
|
70
|
+
- name: Configure Docker for Artifact Registry
|
|
71
|
+
run: gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
|
|
72
|
+
|
|
73
|
+
- name: Build & push image (multi-stage Node Dockerfile)
|
|
74
|
+
run: |
|
|
75
|
+
IMG="${AR_IMAGE}:${{ steps.vars.outputs.tag }}"
|
|
76
|
+
docker build --platform=linux/amd64 -t "$IMG" .
|
|
77
|
+
docker push "$IMG"
|
|
78
|
+
echo "IMG=$IMG" >> "$GITHUB_ENV"
|
|
79
|
+
|
|
80
|
+
- name: Deploy to Cloud Run (image only; preserves env/secrets)
|
|
81
|
+
run: |
|
|
82
|
+
# PROD lands at 0% traffic behind a tag (canary); verify the tagged
|
|
83
|
+
# URL, then promote with `gcloud run services update-traffic`.
|
|
84
|
+
# QA keeps deploying live. Mirrors vh-api-gateway deploy-gcp.yml.
|
|
85
|
+
#
|
|
86
|
+
# --vpc-egress is pinned: gcloud 572 flipped the template to
|
|
87
|
+
# all-traffic on an image-only update; with no Cloud NAT that cuts
|
|
88
|
+
# the service's internet egress.
|
|
89
|
+
EXTRA=""
|
|
90
|
+
if [ "${{ steps.vars.outputs.traffic }}" = "canary" ]; then
|
|
91
|
+
EXTRA="--no-traffic --tag ${{ steps.vars.outputs.tag }}"
|
|
92
|
+
fi
|
|
93
|
+
gcloud run deploy "${{ steps.vars.outputs.service }}" \
|
|
94
|
+
--image "$IMG" \
|
|
95
|
+
--project "$GCP_PROJECT" \
|
|
96
|
+
--region "$GCP_REGION" \
|
|
97
|
+
--vpc-egress=private-ranges-only \
|
|
98
|
+
$EXTRA \
|
|
99
|
+
--quiet
|
|
100
|
+
|
|
101
|
+
- name: Summary
|
|
102
|
+
run: echo "Deployed **${{ steps.vars.outputs.service }}** with \`$IMG\`" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -7,12 +7,32 @@ on:
|
|
|
7
7
|
- 'src/**'
|
|
8
8
|
- 'package.json'
|
|
9
9
|
- 'bin/**'
|
|
10
|
+
# Manual publish (e.g. to ship a security fix that landed while publishing was broken).
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
inputs:
|
|
13
|
+
version:
|
|
14
|
+
description: 'Exact version to publish (e.g. 1.1.0). Empty = automatic patch bump. Must be greater than the highest existing tag and package.json.'
|
|
15
|
+
required: false
|
|
16
|
+
type: string
|
|
17
|
+
|
|
18
|
+
# One publish at a time: two runs would compute the same next version.
|
|
19
|
+
concurrency:
|
|
20
|
+
group: npm-publish
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
# Auth is npm Trusted Publishing (OIDC): no long-lived NPM_TOKEN to expire or leak
|
|
24
|
+
# (security review 2026-10-11, M13). The NPM_TOKEN secret expired and every publish
|
|
25
|
+
# since 2026-04-29 failed with "E404 PUT .../deepdebug-local-agent".
|
|
26
|
+
# One-time setup on npmjs.com (package owner): deepdebug-local-agent -> Settings ->
|
|
27
|
+
# Trusted Publisher -> GitHub Actions: org VISIONHAMMER, repo deepdebug-local-agent,
|
|
28
|
+
# workflow npm-publish.yml.
|
|
10
29
|
|
|
11
30
|
jobs:
|
|
12
31
|
publish:
|
|
13
32
|
runs-on: ubuntu-latest
|
|
14
33
|
permissions:
|
|
15
34
|
contents: write
|
|
35
|
+
id-token: write # OIDC token for npm Trusted Publishing (+ provenance)
|
|
16
36
|
|
|
17
37
|
steps:
|
|
18
38
|
- name: Checkout
|
|
@@ -24,9 +44,13 @@ jobs:
|
|
|
24
44
|
- name: Setup Node.js
|
|
25
45
|
uses: actions/setup-node@v4
|
|
26
46
|
with:
|
|
27
|
-
node-version: '
|
|
47
|
+
node-version: '24'
|
|
28
48
|
registry-url: 'https://registry.npmjs.org'
|
|
29
49
|
|
|
50
|
+
- name: npm with Trusted Publishing support
|
|
51
|
+
# OIDC publishing needs npm >= 11.5.1.
|
|
52
|
+
run: npm install -g npm@^11.5.1 && npm --version
|
|
53
|
+
|
|
30
54
|
- name: Install dependencies
|
|
31
55
|
run: npm install
|
|
32
56
|
|
|
@@ -40,10 +64,41 @@ jobs:
|
|
|
40
64
|
git add package-lock.json || true
|
|
41
65
|
git diff --staged --quiet || git commit -m "chore: update package-lock.json [skip ci]"
|
|
42
66
|
|
|
43
|
-
- name: Bump patch
|
|
67
|
+
- name: Bump version (patch, or the exact dispatch input)
|
|
68
|
+
env:
|
|
69
|
+
INPUT_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }}
|
|
44
70
|
run: |
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
# Bump from max(highest existing tag, package.json) so the new tag can
|
|
72
|
+
# never collide with an already-pushed tag (package.json had drifted
|
|
73
|
+
# behind the tags, which made `npm version patch` fail with
|
|
74
|
+
# "tag vX.Y.Z already exists" on every push to main).
|
|
75
|
+
git fetch --tags --quiet
|
|
76
|
+
LATEST_TAG="$(git tag --sort=-v:refname | head -1)"
|
|
77
|
+
LATEST_TAG="${LATEST_TAG#v}"
|
|
78
|
+
PKG="$(node -p "require('./package.json').version")"
|
|
79
|
+
BASE="$(printf '%s\n%s\n' "${LATEST_TAG:-0.0.0}" "$PKG" | sort -V | tail -1)"
|
|
80
|
+
# Compute the next patch version up front and bump in ONE `npm version`
|
|
81
|
+
# call. A separate `npm version "$BASE" --no-git-tag-version` rewrites
|
|
82
|
+
# package.json/package-lock.json whenever the tag is ahead of
|
|
83
|
+
# package.json, leaving the tree dirty so the following
|
|
84
|
+
# `npm version patch` aborts with "Git working directory not clean".
|
|
85
|
+
NEXT="$(node -e 'const [a,b,c]=process.argv[1].split(".").map(Number); console.log(`${a}.${b}.${c+1}`)' "$BASE")"
|
|
86
|
+
# Release override (workflow_dispatch input `version`, e.g. 1.1.0): used
|
|
87
|
+
# as-is instead of the patch bump, so a minor/major release is not turned
|
|
88
|
+
# into 1.1.1 by the automatic bump. Read from env, never interpolated.
|
|
89
|
+
if [ -n "${INPUT_VERSION}" ]; then
|
|
90
|
+
if ! printf '%s' "$INPUT_VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
91
|
+
echo "::error::version input '$INPUT_VERSION' is not X.Y.Z"; exit 1
|
|
92
|
+
fi
|
|
93
|
+
if [ "$(printf '%s\n%s\n' "$BASE" "$INPUT_VERSION" | sort -V | tail -1)" != "$INPUT_VERSION" ] || [ "$INPUT_VERSION" = "$BASE" ]; then
|
|
94
|
+
echo "::error::version input $INPUT_VERSION must be greater than $BASE (highest existing tag/package.json)"; exit 1
|
|
95
|
+
fi
|
|
96
|
+
NEXT="$INPUT_VERSION"
|
|
97
|
+
fi
|
|
98
|
+
# Commit + tag LOCALLY only. They are pushed after a successful publish, so a
|
|
99
|
+
# failed publish no longer burns a version (1.0.24..1.0.38 were tagged but
|
|
100
|
+
# never published while the token was expired).
|
|
101
|
+
npm version "$NEXT" -m "ci: auto bump to %s [skip ci]"
|
|
47
102
|
|
|
48
103
|
- name: Check if version exists
|
|
49
104
|
id: version_check
|
|
@@ -59,14 +114,20 @@ jobs:
|
|
|
59
114
|
echo "Version $PACKAGE_VERSION is new"
|
|
60
115
|
echo "exists=false" >> $GITHUB_OUTPUT
|
|
61
116
|
fi
|
|
62
|
-
env:
|
|
63
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
64
117
|
|
|
65
118
|
- name: Publish to NPM
|
|
66
119
|
if: steps.version_check.outputs.exists == 'false'
|
|
120
|
+
# No --provenance: this repository is private and npm rejects provenance
|
|
121
|
+
# statements for private source repositories (E422 "Unsupported GitHub Actions
|
|
122
|
+
# source repository visibility"). Trusted Publishing (OIDC) still authenticates
|
|
123
|
+
# the publish. Re-add --provenance if the repository ever becomes public.
|
|
67
124
|
run: npm publish --access public
|
|
68
|
-
|
|
69
|
-
|
|
125
|
+
|
|
126
|
+
- name: Push version bump and tag
|
|
127
|
+
run: |
|
|
128
|
+
# main may have moved while we published: replay the bump commit on top.
|
|
129
|
+
git pull --rebase origin main
|
|
130
|
+
git push origin main --follow-tags
|
|
70
131
|
|
|
71
132
|
- name: Skip publish (version exists)
|
|
72
133
|
if: steps.version_check.outputs.exists == 'true'
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# AGENTS.md - deepdebug-local-agent
|
|
2
|
+
|
|
3
|
+
Instructions for AI coding agents (Codex, Cursor, Copilot, Gemini, Claude Code and others).
|
|
4
|
+
Claude Code also reads `CLAUDE.md`; the same rules apply to every agent.
|
|
5
|
+
|
|
6
|
+
## Read first
|
|
7
|
+
|
|
8
|
+
1. `.claude/context.md`: what this repo is in the VisionHammer v2 architecture, its
|
|
9
|
+
neighbours, where things live, how to run, test, deploy and roll back, and the gotchas.
|
|
10
|
+
2. `.claude/standards/README.md`, then the files it lists: `clean-code.md`, `solid.md`,
|
|
11
|
+
`simplicity.md`, `layered-architecture.md`, `security-owasp.md`, `testing.md`,
|
|
12
|
+
`code-review-checklist.md` and `node.md`.
|
|
13
|
+
3. `CLAUDE.md`: repo rules. They win over the generic standards.
|
|
14
|
+
|
|
15
|
+
## Always
|
|
16
|
+
|
|
17
|
+
- PRs target `main` (publishes the npm package); Cloud Run deploy is manual.
|
|
18
|
+
- Runs inside customer infrastructure: argument-array process execution, paths confined to the workspace, no LLM calls, no secrets in logs.
|
|
19
|
+
- Never print, log or commit secrets. Provider keys exist only in vh-litellm.
|
|
20
|
+
- Verify on the deployed artefact (curl, revision logs, bundle grep), not only on the diff.
|
|
21
|
+
- Small PRs with one intent each. Open PRs; a human merges them.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.1.0 (prepared, not yet published)
|
|
4
|
+
|
|
5
|
+
Security release (security review 2026-10-11, C1 and H4). The agent now fails
|
|
6
|
+
closed by default. Read "Upgrade" before rolling it out to agents whose
|
|
7
|
+
platform side does not sign commands yet.
|
|
8
|
+
|
|
9
|
+
### Changed defaults
|
|
10
|
+
|
|
11
|
+
- **Signed commands: `enforce` by default.** `LOCAL_AGENT_SIGNATURE_MODE`
|
|
12
|
+
defaults to `enforce` (was `warn`) and an unrecognised value also means
|
|
13
|
+
`enforce`. A request without a valid `X-VH-*` signature is refused.
|
|
14
|
+
- **Loopback bind by default.** Without `LOCAL_AGENT_BIND_HOST`, the agent binds
|
|
15
|
+
`127.0.0.1` unless a token (`LOCAL_AGENT_TOKEN` / `AGENT_SHARED_SECRET`) or
|
|
16
|
+
Cloud Run is present (or `LOCAL_AGENT_AUTH` is `compat`/`off`).
|
|
17
|
+
- **Helm: token required, NetworkPolicy deny-ingress.** `config.agentToken`
|
|
18
|
+
is required (rendered as `LOCAL_AGENT_TOKEN`; `helm template` fails without
|
|
19
|
+
it). The chart ships a NetworkPolicy that denies all ingress except the peers
|
|
20
|
+
listed in `networkPolicy.allowFrom` (default: none; the agent talks to the
|
|
21
|
+
platform over an outbound tunnel). Chart `version`/`appVersion` are now 1.1.0.
|
|
22
|
+
- **H4: no shell for request text.** `/workspace/search` runs grep through
|
|
23
|
+
`execFile` with an argv list, `/workspace/build-push` validates the workspace
|
|
24
|
+
id and runs tar through `execFile`, and `/setup/run-auth-command` accepts only
|
|
25
|
+
allowlisted interactive logins, spawned without a shell.
|
|
26
|
+
- Already in 1.0.35 and unchanged here: exec policy `enforce`, `LOCAL_AGENT_AUTH`
|
|
27
|
+
loopback/token perimeter (`docs/signed-commands.md`).
|
|
28
|
+
|
|
29
|
+
### Compatibility with the `X-VH-*` signature
|
|
30
|
+
|
|
31
|
+
Protocol v1 is unchanged (`VH-AGENT-SIG-V1`, Ed25519 over method, path, body
|
|
32
|
+
hash, tenant, workspace, timestamp, nonce; headers `X-VH-Key-Id`,
|
|
33
|
+
`X-VH-Timestamp`, `X-VH-Nonce`, `X-VH-Tenant-Id`, `X-VH-Workspace-Id`,
|
|
34
|
+
`X-VH-Signature`). The trusted key id is `vh-2026-09`; rotation is
|
|
35
|
+
unchanged. A platform that already signs (vh-api-gateway, visionhammer-agents)
|
|
36
|
+
needs no change. `X-Agent-Token` stays as the second factor.
|
|
37
|
+
|
|
38
|
+
### Build and release
|
|
39
|
+
|
|
40
|
+
- Release procedure for an exact version without the automatic patch bump:
|
|
41
|
+
`docs/releasing.md` (`npm-publish.yml` gains a `version` dispatch input).
|
|
42
|
+
- Optional cosign (keyless) signature, SPDX SBOM and SLSA v1 provenance for the
|
|
43
|
+
`local-agent-full` image, behind `supply_chain` / `BYOC_SUPPLY_CHAIN`
|
|
44
|
+
(off by default; `docs/byoc-agent-image.md`).
|
|
45
|
+
- Helm `values.yaml`: removed a dead duplicate `networkPolicy` block (the later
|
|
46
|
+
key already won; no behaviour change).
|
|
47
|
+
|
|
48
|
+
### Upgrade
|
|
49
|
+
|
|
50
|
+
1. Make sure the platform signs requests to this agent (gateway and agents with
|
|
51
|
+
the signing key) before upgrading an agent in production.
|
|
52
|
+
2. Optional soak: set `LOCAL_AGENT_SIGNATURE_MODE=warn` on the agent, watch
|
|
53
|
+
`[agent-sig] WARN` and `[exec-policy] WARN`, then remove the override.
|
|
54
|
+
3. Helm: set `config.agentToken` (`--set-file` or an existing secret flow) and,
|
|
55
|
+
if a caller must reach the pod, list it in `networkPolicy.allowFrom`.
|
|
56
|
+
4. Agents reached directly over the network need a token or
|
|
57
|
+
`LOCAL_AGENT_BIND_HOST`; otherwise they only answer on `127.0.0.1`.
|
|
58
|
+
5. BYOC: pin the new image as `local-agent-full:1.1.0@sha256:<digest>` in the
|
|
59
|
+
gateway (`BYOC_AGENT_IMAGE`). Existing agents keep their image until
|
|
60
|
+
re-provisioned.
|
|
61
|
+
|
|
62
|
+
### Rollback
|
|
63
|
+
|
|
64
|
+
- Per agent, without redeploy of the platform: `LOCAL_AGENT_SIGNATURE_MODE=warn`
|
|
65
|
+
(or `off`), `LOCAL_AGENT_BIND_HOST=0.0.0.0` together with a token,
|
|
66
|
+
`networkPolicy.enabled=false` in Helm. These are explicit, logged opt-outs.
|
|
67
|
+
- Version rollback: npm `npm i deepdebug-local-agent@1.0.38`; BYOC image: repin
|
|
68
|
+
the previous `:<semver>@sha256:` (tags are immutable, nothing floats).
|
|
69
|
+
Note 1.0.38 still defaults signatures to `warn` and binds more widely.
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# CLAUDE.md - deepdebug-local-agent
|
|
2
|
+
|
|
3
|
+
## Read first
|
|
4
|
+
1. `.claude/context.md`: what this agent is in the v2 architecture (the platform's hands
|
|
5
|
+
in customer infrastructure), its neighbours, run/test, publish/deploy and gotchas.
|
|
6
|
+
2. `.claude/standards/`: shared VisionHammer standards (clean code, SOLID, OWASP security,
|
|
7
|
+
layers, simplicity, testing, review checklist, `node.md`).
|
|
8
|
+
3. `README.md`: features, legacy connectors, configuration.
|
|
9
|
+
|
|
10
|
+
Non-negotiables: no LLM calls and no provider keys here; exec with argument arrays only;
|
|
11
|
+
paths confined to the workspace; never log secrets or raw customer log payloads beyond
|
|
12
|
+
what an incident needs; PRs target `main` (merging publishes the npm package).
|
|
13
|
+
Personal, uncommitted notes go in `CLAUDE.local.md` (gitignored).
|
|
@@ -13,7 +13,9 @@ AGENT="https://deepdebug-local-agent-qa-575662086506.us-central1.run.app"
|
|
|
13
13
|
GATEWAY="https://deepdebug-gateway-qa-575662086506.us-central1.run.app"
|
|
14
14
|
GCP_CLIENT="gen-lang-client-0961289539"
|
|
15
15
|
SA_EMAIL="deepdebug-agent@${GCP_CLIENT}.iam.gserviceaccount.com"
|
|
16
|
-
|
|
16
|
+
# DB password: never inline it. Read it from Secret Manager (pg-password-qa).
|
|
17
|
+
PG_PASSWORD="$(gcloud secrets versions access latest --secret=pg-password-qa --project=visionhammer)"
|
|
18
|
+
PG="PGPASSWORD=\"$PG_PASSWORD\" psql -h 35.224.155.29 -U deepdebug -d deepdebug"
|
|
17
19
|
WS_ID="b040f1ae-5f3c-4612-9ce1-0b18a5aea303"
|
|
18
20
|
|
|
19
21
|
log() { echo "[$(date '+%H:%M:%S')] $1"; }
|
|
@@ -517,7 +519,7 @@ while [ "$AGENT_DONE" = "false" ]; do
|
|
|
517
519
|
|
|
518
520
|
# ─── CHECK A3: Clone com token real ───
|
|
519
521
|
log "CHECK A3: Clone com token real"
|
|
520
|
-
GIT_TOKEN=$(PGPASSWORD=
|
|
522
|
+
GIT_TOKEN=$(PGPASSWORD="$PG_PASSWORD" psql -h 35.224.155.29 -U deepdebug -d deepdebug -t -c \
|
|
521
523
|
"SELECT t.access_token FROM oauth_tokens t JOIN tenants tn ON tn.id::text=t.tenant_id WHERE t.provider='GITHUB' LIMIT 1;" \
|
|
522
524
|
| tr -d ' \n')
|
|
523
525
|
|
|
@@ -537,7 +539,7 @@ while [ "$AGENT_DONE" = "false" ]; do
|
|
|
537
539
|
|
|
538
540
|
# ─── CHECK A4: /workspace/build-push com SA real ───
|
|
539
541
|
log "CHECK A4: build-push com SA key real"
|
|
540
|
-
SA_KEY_ENC=$(PGPASSWORD=
|
|
542
|
+
SA_KEY_ENC=$(PGPASSWORD="$PG_PASSWORD" psql -h 35.224.155.29 -U deepdebug -d deepdebug -t -c \
|
|
541
543
|
"SELECT service_account_key FROM oauth_tokens WHERE tenant_id='63922779-7321-4e79-b0f0-63890cd0d98e' AND provider='GCP';" \
|
|
542
544
|
| tr -d ' \n')
|
|
543
545
|
ENC_KEY=$(gcloud secrets versions access latest --secret=encryption-key-qa --project=insptechai 2>/dev/null)
|
package/Dockerfile
CHANGED
|
@@ -120,6 +120,10 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
|
120
120
|
ENV NODE_ENV=production
|
|
121
121
|
ENV PORT=5055
|
|
122
122
|
ENV WORKSPACES_MOUNT=/mnt/workspaces
|
|
123
|
+
# env-compat preload: maps legacy env names (DEEPDEBUG_API_URL/TENANT_ID/
|
|
124
|
+
# WORKSPACE_PATH) to the canonical GATEWAY_URL/TENANT_ID/WORKSPACE_ROOT before
|
|
125
|
+
# server.js is evaluated. --require (CJS) runs before the ESM entry module.
|
|
126
|
+
ENV NODE_OPTIONS="--require /app/src/siblings/env-compat.cjs"
|
|
123
127
|
|
|
124
128
|
EXPOSE 5055
|
|
125
129
|
|
package/Dockerfile.full
CHANGED
|
@@ -33,8 +33,51 @@ RUN apt-get update && \
|
|
|
33
33
|
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
|
34
34
|
ENV PATH=$PATH:$JAVA_HOME/bin:/usr/share/maven/bin
|
|
35
35
|
|
|
36
|
+
# Swift 5.10 toolchain — enables `swift build` for SwiftPM projects and
|
|
37
|
+
# `swiftc -typecheck` / `swiftc -parse` for iOS/Xcode projects whose imports
|
|
38
|
+
# Linux can resolve. Apple-framework imports (UIKit/SwiftUI/Combine/etc.)
|
|
39
|
+
# still need macOS — handled gracefully in src/exec-utils.js by falling
|
|
40
|
+
# back to `swiftc -parse` (syntax-only validation).
|
|
41
|
+
# Image-size cost: ~1.5 GB decompressed. Accepted for the BYOC full-tools
|
|
42
|
+
# agent image; not pulled by the lean Cloud Run QA path (uses Dockerfile).
|
|
43
|
+
# Note on platform mismatch: base is node:20-slim (Debian 12/bookworm), but
|
|
44
|
+
# swift.org does not publish a debian12 tarball for 5.10. Ubuntu 22.04 build
|
|
45
|
+
# runs cleanly on Debian 12 (newer glibc is backward-compatible with the
|
|
46
|
+
# ubuntu2204 binary), so we install the ubuntu22.04 tarball + Debian 12
|
|
47
|
+
# runtime deps. swift --version smoke-test catches any glibc mismatch at
|
|
48
|
+
# build time.
|
|
49
|
+
ARG SWIFT_VERSION=5.10
|
|
50
|
+
ARG SWIFT_PLATFORM=ubuntu22.04
|
|
51
|
+
ARG SWIFT_PLATFORM_DIR=ubuntu2204
|
|
52
|
+
RUN apt-get update && \
|
|
53
|
+
apt-get install -y --no-install-recommends \
|
|
54
|
+
binutils \
|
|
55
|
+
libc6-dev \
|
|
56
|
+
libcurl4-openssl-dev \
|
|
57
|
+
libedit2 \
|
|
58
|
+
libgcc-12-dev \
|
|
59
|
+
libncurses6 \
|
|
60
|
+
libpython3.11 \
|
|
61
|
+
libsqlite3-0 \
|
|
62
|
+
libstdc++-12-dev \
|
|
63
|
+
libxml2-dev \
|
|
64
|
+
libz3-dev \
|
|
65
|
+
pkg-config \
|
|
66
|
+
tzdata \
|
|
67
|
+
uuid-dev \
|
|
68
|
+
zlib1g-dev \
|
|
69
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
70
|
+
&& cd /tmp \
|
|
71
|
+
&& curl -fsSL "https://download.swift.org/swift-${SWIFT_VERSION}-release/${SWIFT_PLATFORM_DIR}/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-${SWIFT_PLATFORM}.tar.gz" -o swift.tar.gz \
|
|
72
|
+
&& tar xzf swift.tar.gz \
|
|
73
|
+
&& mv "swift-${SWIFT_VERSION}-RELEASE-${SWIFT_PLATFORM}" /opt/swift \
|
|
74
|
+
&& rm swift.tar.gz \
|
|
75
|
+
&& ln -s /opt/swift/usr/bin/swift /usr/local/bin/swift \
|
|
76
|
+
&& ln -s /opt/swift/usr/bin/swiftc /usr/local/bin/swiftc \
|
|
77
|
+
&& swift --version
|
|
78
|
+
|
|
36
79
|
# Verify all tools are installed
|
|
37
|
-
RUN java -version && mvn -version && node -v && git --version
|
|
80
|
+
RUN java -version && mvn -version && node -v && git --version && swift --version
|
|
38
81
|
|
|
39
82
|
# Git safe directory for NFS mounted workspaces
|
|
40
83
|
RUN git config --global --add safe.directory '*'
|
|
@@ -55,9 +98,18 @@ RUN mkdir -p /home/deepdebug/.m2 && chown -R deepdebug:deepdebug /home/deepdebug
|
|
|
55
98
|
# Workspace mount point
|
|
56
99
|
RUN mkdir -p /mnt/workspaces && chown -R deepdebug:deepdebug /mnt/workspaces
|
|
57
100
|
|
|
58
|
-
|
|
101
|
+
# Port aligned to 5055 to match Dockerfile, docker-compose, Helm and the
|
|
102
|
+
# server.js default (PORT || LOCAL_AGENT_PORT || 5055). 8080 here conflicted.
|
|
103
|
+
EXPOSE 5055
|
|
59
104
|
|
|
60
105
|
ENV NODE_ENV=production
|
|
61
|
-
ENV PORT=
|
|
106
|
+
ENV PORT=5055
|
|
107
|
+
# env-compat preload (see Dockerfile): legacy->canonical env mapping before eval.
|
|
108
|
+
ENV NODE_OPTIONS="--require /app/src/siblings/env-compat.cjs"
|
|
109
|
+
|
|
110
|
+
# SECURITY (2026-10-11): the slim Dockerfile already drops to the unprivileged
|
|
111
|
+
# user; this image ran everything (model-authored commands included) as root.
|
|
112
|
+
RUN su deepdebug -c "git config --global --add safe.directory '*'"
|
|
113
|
+
USER deepdebug
|
|
62
114
|
|
|
63
115
|
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.
|
package/bin/install.js
CHANGED
|
@@ -17,7 +17,7 @@ import fs from 'fs';
|
|
|
17
17
|
import path from 'path';
|
|
18
18
|
import os from 'os';
|
|
19
19
|
import crypto from 'crypto';
|
|
20
|
-
import { spawn, execSync } from 'child_process';
|
|
20
|
+
import { spawn, execSync, execFileSync } from 'child_process';
|
|
21
21
|
import readline from 'readline';
|
|
22
22
|
|
|
23
23
|
// ============================================
|
|
@@ -26,7 +26,14 @@ import readline from 'readline';
|
|
|
26
26
|
const CONFIG_DIR = path.join(os.homedir(), '.deepdebug');
|
|
27
27
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
28
28
|
const MACHINE_ID_FILE = path.join(CONFIG_DIR, 'machine-id');
|
|
29
|
-
|
|
29
|
+
// Single-sourced default, consistent with docker-compose / Helm / env.example /
|
|
30
|
+
// canonical prod host. Verified against DNS + Cloud Run domain mapping:
|
|
31
|
+
// api.visionhammer.io -> ghs.googlehosted.com (Cloud Run mapping for the prod
|
|
32
|
+
// deepdebug-gateway service). api.deepdebug.ai has NO DNS record and did not
|
|
33
|
+
// answer during the audit, so it must NOT be the default. The previous default
|
|
34
|
+
// was also a stale, now-dead QA run.app hash (deepdebug-gateway-lszyf7c4ia).
|
|
35
|
+
// Override per environment with DEEPDEBUG_API_URL.
|
|
36
|
+
const API_BASE_URL = process.env.DEEPDEBUG_API_URL || 'https://api.visionhammer.io';
|
|
30
37
|
const DOCKER_IMAGE = 'williambella/deepdebug-local-agent:latest';
|
|
31
38
|
|
|
32
39
|
// ============================================
|
|
@@ -421,7 +428,7 @@ function startDockerAgent(config) {
|
|
|
421
428
|
} catch {}
|
|
422
429
|
|
|
423
430
|
logInfo('Pulling latest DeepDebug Local Agent image...');
|
|
424
|
-
|
|
431
|
+
execFileSync('docker', ['pull', DOCKER_IMAGE], { stdio: 'inherit' });
|
|
425
432
|
|
|
426
433
|
// Prepare paths for Docker
|
|
427
434
|
let configMount = CONFIG_DIR;
|
|
@@ -436,7 +443,9 @@ function startDockerAgent(config) {
|
|
|
436
443
|
const dockerArgs = [
|
|
437
444
|
'run', '-d',
|
|
438
445
|
'--name', 'deepdebug-agent',
|
|
439
|
-
|
|
446
|
+
// SECURITY: publish on loopback only. '5055:5055' exposed the agent
|
|
447
|
+
// (shell exec + workspace write API) on every host interface.
|
|
448
|
+
'-p', '127.0.0.1:5055:5055',
|
|
440
449
|
'-v', `${configMount}:/home/deepdebug/.deepdebug:ro`,
|
|
441
450
|
'-v', `${projectsMount}:/workspace:rw`,
|
|
442
451
|
'-e', `GATEWAY_URL=${config.gatewayUrl}`,
|
|
@@ -448,7 +457,9 @@ function startDockerAgent(config) {
|
|
|
448
457
|
];
|
|
449
458
|
|
|
450
459
|
logInfo('Starting Docker container with workspace mounted...');
|
|
451
|
-
|
|
460
|
+
// execFileSync (no shell): paths/config values are passed verbatim, so a
|
|
461
|
+
// projects path with spaces or shell metacharacters cannot break out.
|
|
462
|
+
execFileSync('docker', dockerArgs, { stdio: 'inherit' });
|
|
452
463
|
logSuccess('DeepDebug Local Agent started successfully!');
|
|
453
464
|
return true;
|
|
454
465
|
} catch (error) {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Manual fallback for the BYOC "full" agent image (the primary path is the
|
|
2
|
+
# GitHub Actions workflow .github/workflows/build-byoc-image.yml).
|
|
3
|
+
# Replaces cloudbuild-full-v3.yaml, which pushed a floating :v3 tag to the
|
|
4
|
+
# deactivated insptechai project.
|
|
5
|
+
#
|
|
6
|
+
# Usage (from a clean checkout of main; both substitutions are required):
|
|
7
|
+
# gcloud builds submit --project visionhammer --config cloudbuild-full.yaml \
|
|
8
|
+
# --substitutions=_VERSION=1.0.31,_GIT_SHA=$(git rev-parse HEAD) .
|
|
9
|
+
#
|
|
10
|
+
# Pushes :<_VERSION> and :<_GIT_SHA> — never a floating tag. Pin the gateway to
|
|
11
|
+
# the resulting digest (deepdebug.byoc.agent-image in vh-api-gateway).
|
|
12
|
+
substitutions:
|
|
13
|
+
_IMAGE: 'us-central1-docker.pkg.dev/visionhammer/visionhammer-docker-public/local-agent-full'
|
|
14
|
+
_VERSION: ''
|
|
15
|
+
_GIT_SHA: ''
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- id: guard
|
|
19
|
+
name: 'gcr.io/cloud-builders/gcloud'
|
|
20
|
+
entrypoint: 'bash'
|
|
21
|
+
args:
|
|
22
|
+
- '-c'
|
|
23
|
+
- |
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
[ -n "${_VERSION}" ] && [ -n "${_GIT_SHA}" ] || { echo "_VERSION and _GIT_SHA are required"; exit 1; }
|
|
26
|
+
if gcloud artifacts docker images describe "${_IMAGE}:${_VERSION}" >/dev/null 2>&1; then
|
|
27
|
+
echo "${_IMAGE}:${_VERSION} already exists; bump the version instead of overwriting"; exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
- id: build
|
|
31
|
+
name: 'gcr.io/cloud-builders/docker'
|
|
32
|
+
args:
|
|
33
|
+
- 'build'
|
|
34
|
+
- '--platform=linux/amd64'
|
|
35
|
+
- '-f'
|
|
36
|
+
- 'Dockerfile.full'
|
|
37
|
+
- '--label'
|
|
38
|
+
- 'org.opencontainers.image.revision=${_GIT_SHA}'
|
|
39
|
+
- '--label'
|
|
40
|
+
- 'org.opencontainers.image.version=${_VERSION}'
|
|
41
|
+
- '-t'
|
|
42
|
+
- '${_IMAGE}:${_VERSION}'
|
|
43
|
+
- '-t'
|
|
44
|
+
- '${_IMAGE}:${_GIT_SHA}'
|
|
45
|
+
- '.'
|
|
46
|
+
timeout: '3000s'
|
|
47
|
+
|
|
48
|
+
images:
|
|
49
|
+
- '${_IMAGE}:${_VERSION}'
|
|
50
|
+
- '${_IMAGE}:${_GIT_SHA}'
|
|
51
|
+
|
|
52
|
+
options:
|
|
53
|
+
logging: CLOUD_LOGGING_ONLY
|
|
54
|
+
machineType: 'E2_HIGHCPU_32'
|
|
55
|
+
diskSizeGb: 50
|
|
56
|
+
|
|
57
|
+
timeout: '3600s'
|
package/docker-compose.yml
CHANGED
|
@@ -63,9 +63,11 @@ services:
|
|
|
63
63
|
environment:
|
|
64
64
|
- NODE_ENV=production
|
|
65
65
|
- PORT=5055
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
66
|
+
# Names aligned to what src/server.js actually reads (server.js is frozen):
|
|
67
|
+
# GATEWAY_URL (server.js:73), TENANT_ID (:7505), WORKSPACE_ROOT (:637).
|
|
68
|
+
- GATEWAY_URL=${GATEWAY_URL:-https://api.deepdebug.ai}
|
|
69
|
+
- TENANT_ID=${TENANT_ID}
|
|
70
|
+
- WORKSPACE_ROOT=/workspace
|
|
69
71
|
- LOG_LEVEL=${LOG_LEVEL:-info}
|
|
70
72
|
|
|
71
73
|
# ─────────────────────────────────────────
|