forge-workflow 0.0.10 → 0.1.0-beta.3
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/rules/{greptile-review-process.md → review-process.md} +56 -41
- package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
- package/.cursor/rules/permissions-guidance.mdc +2 -2
- package/.forge/hooks/check-tdd.js +82 -5
- package/.forge/hooks/forge-native-hook.js +431 -0
- package/.forge/protected-paths.yaml +157 -0
- package/AGENTS.md +151 -61
- package/CHANGELOG.md +709 -0
- package/CLAUDE.md +9 -118
- package/QUICKSTART.md +175 -0
- package/README.md +275 -365
- package/bin/forge-cmd.js +120 -9
- package/bin/forge-preflight.js +26 -5
- package/bin/forge.js +532 -489
- package/docs/INDEX.md +93 -0
- package/docs/PROJECT_DESIGN.md +685 -0
- package/docs/architecture/index.md +66 -0
- package/docs/architecture/notes/README.md +35 -0
- package/docs/architecture/subsystems/README.md +46 -0
- package/docs/forge/TOOLCHAIN.md +670 -0
- package/docs/forge/VALIDATION.md +82 -0
- package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
- package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
- package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
- package/docs/guides/GREPTILE_SETUP.md +46 -0
- package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
- package/docs/guides/MIGRATION.md +56 -0
- package/docs/guides/SETUP.md +121 -0
- package/docs/guides/SUPPORT.md +190 -0
- package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
- package/docs/guides/memory-backends.md +183 -0
- package/docs/reference/ADAPTERS.md +128 -0
- package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
- package/docs/reference/COMMANDS.md +214 -0
- package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
- package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
- package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
- package/docs/reference/HERMES_INTEGRATION.md +118 -0
- package/docs/reference/INSIGHTS_RECAP.md +63 -0
- package/docs/reference/INSTALL.md +164 -0
- package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
- package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
- package/docs/reference/RELEASE.md +68 -0
- package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
- package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
- package/docs/reference/SKILLS.md +35 -0
- package/docs/reference/STATUS_BOARD.md +80 -0
- package/docs/reference/TEMPLATES.md +106 -0
- package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
- package/docs/reference/VALIDATION.md +82 -0
- package/docs/reference/agent-permissions.md +169 -0
- package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
- package/docs/reference/control-plane-guarantees.md +125 -0
- package/docs/reference/dependency-chain.md +331 -0
- package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
- package/docs/reference/forge-kernel-schema.md +72 -0
- package/docs/reference/kernel-conflict-evaluators.md +27 -0
- package/docs/reference/patch-md-format.md +77 -0
- package/docs/reference/protected-state-surfaces.md +59 -0
- package/docs/reference/shepherd.md +155 -0
- package/docs/reference/superpowers-analysis.md +320 -0
- package/docs/reference/superpowers-integration-options.md +404 -0
- package/docs/reference/test-environment.md +519 -0
- package/docs/reference/upgrade-safety.md +59 -0
- package/lefthook.yml +18 -0
- package/lib/activation/ensure-forge-home.js +135 -0
- package/lib/adapter-cli.js +307 -0
- package/lib/adapters/beads-issue-adapter.js +127 -0
- package/lib/adapters/beads-kernel-compat.js +1109 -0
- package/lib/adapters/greptile-review-adapter.js +141 -0
- package/lib/adapters/kernel-issue-adapter.js +101 -0
- package/lib/adapters/pr-state-adapter.js +484 -0
- package/lib/adoption-profiles.js +139 -0
- package/lib/agents/README.md +2 -6
- package/lib/agents/claude.plugin.json +3 -8
- package/lib/agents/codex.plugin.json +9 -1
- package/lib/agents/cursor.plugin.json +2 -6
- package/lib/agents/hermes.plugin.json +22 -0
- package/lib/agents-config.js +39 -1236
- package/lib/audit-evidence.js +282 -0
- package/lib/beads-detect.js +60 -0
- package/lib/beads-nudge.js +91 -0
- package/lib/beads-setup.js +121 -0
- package/lib/beads-sync-scaffold.js +25 -101
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_aliases.js +248 -0
- package/lib/commands/_issue.js +780 -77
- package/lib/commands/_manifest.js +93 -0
- package/lib/commands/_registry.js +99 -34
- package/lib/commands/_resolve-command-opts.js +230 -0
- package/lib/commands/_serve-security.js +270 -0
- package/lib/commands/adapter.js +12 -0
- package/lib/commands/add.js +118 -0
- package/lib/commands/audit.js +70 -0
- package/lib/commands/blocked.js +5 -0
- package/lib/commands/board.js +64 -0
- package/lib/commands/claim.js +21 -2
- package/lib/commands/claims.js +7 -0
- package/lib/commands/clean.js +485 -75
- package/lib/commands/close.js +2 -2
- package/lib/commands/comment.js +5 -0
- package/lib/commands/control.js +148 -0
- package/lib/commands/create.js +2 -2
- package/lib/commands/dev.js +185 -7
- package/lib/commands/doc-gate.js +336 -0
- package/lib/commands/doctor.js +156 -0
- package/lib/commands/explain.js +15 -0
- package/lib/commands/export.js +237 -0
- package/lib/commands/gate.js +209 -0
- package/lib/commands/hooks.js +377 -0
- package/lib/commands/inbox.js +118 -0
- package/lib/commands/init.js +604 -0
- package/lib/commands/insights.js +79 -0
- package/lib/commands/issue.js +12 -1
- package/lib/commands/issues.js +17 -0
- package/lib/commands/lint.js +5 -0
- package/lib/commands/list.js +2 -2
- package/lib/commands/memory.js +81 -0
- package/lib/commands/merge.js +312 -0
- package/lib/commands/migrate.js +362 -0
- package/lib/commands/new.js +12 -0
- package/lib/commands/options.js +241 -0
- package/lib/commands/orient.js +13 -0
- package/lib/commands/orphans.js +5 -0
- package/lib/commands/patch.js +67 -0
- package/lib/commands/plan.js +481 -29
- package/lib/commands/pr.js +88 -0
- package/lib/commands/preflight.js +211 -0
- package/lib/commands/prime.js +13 -0
- package/lib/commands/push.js +135 -2
- package/lib/commands/ready.js +2 -2
- package/lib/commands/recall.js +171 -0
- package/lib/commands/recap.js +75 -0
- package/lib/commands/recommend.js +0 -1
- package/lib/commands/release.js +104 -0
- package/lib/commands/remember.js +140 -0
- package/lib/commands/role.js +99 -0
- package/lib/commands/serve.js +581 -0
- package/lib/commands/setup.js +900 -971
- package/lib/commands/shepherd.js +501 -0
- package/lib/commands/ship.js +59 -1
- package/lib/commands/show.js +2 -2
- package/lib/commands/stage.js +192 -0
- package/lib/commands/stale.js +5 -0
- package/lib/commands/status.js +158 -21
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +4 -1
- package/lib/commands/test.js +43 -27
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +43 -18
- package/lib/commands/worktree.js +362 -99
- package/lib/config-writer.js +202 -0
- package/lib/control-plane.js +236 -0
- package/lib/core/runtime-graph.js +977 -0
- package/lib/dep-guard/keyword-ripple.js +2 -2
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +35 -9
- package/lib/doc-gate/declaration.js +177 -0
- package/lib/doc-gate/detect.js +289 -0
- package/lib/doc-gate/gate.js +375 -0
- package/lib/doc-gate/okf-config.js +128 -0
- package/lib/doc-gate/okf.js +429 -0
- package/lib/docs-command.js +1161 -6
- package/lib/forge-issues.js +382 -11
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +192 -0
- package/lib/global-flags.js +104 -0
- package/lib/greptile-match.js +7 -63
- package/lib/grounding/context-events.js +230 -0
- package/lib/grounding/read-first.js +112 -0
- package/lib/harness-capability-matrix.js +380 -0
- package/lib/hook-global-installer.js +347 -0
- package/lib/hook-renderer.js +541 -0
- package/lib/inbox.js +391 -0
- package/lib/insights.js +397 -0
- package/lib/issue-adapter.js +156 -0
- package/lib/issue-backend.js +145 -0
- package/lib/issue-render.js +220 -0
- package/lib/kernel/backing-issue.js +311 -0
- package/lib/kernel/broker.js +1218 -0
- package/lib/kernel/cli-broker-factory.js +130 -0
- package/lib/kernel/conflict-signal.js +82 -0
- package/lib/kernel/evaluators.js +195 -0
- package/lib/kernel/fs-class.js +495 -0
- package/lib/kernel/issue-command-contract.js +559 -0
- package/lib/kernel/issue-id-resolver.js +186 -0
- package/lib/kernel/lease-enforcer.js +158 -0
- package/lib/kernel/migrations.js +333 -0
- package/lib/kernel/owned-kernel.js +43 -0
- package/lib/kernel/planning-buckets-schema.js +109 -0
- package/lib/kernel/projection-jsonl-writer.js +450 -0
- package/lib/kernel/readiness-model.js +329 -0
- package/lib/kernel/schema.js +356 -0
- package/lib/kernel/sqlite-driver.js +2540 -0
- package/lib/kernel/taxonomy-validator.js +394 -0
- package/lib/lefthook-check.js +3 -2
- package/lib/lefthook-wiring.js +413 -0
- package/lib/mcp-config-renderer.js +288 -0
- package/lib/memory/graphiti-mcp.js +106 -0
- package/lib/memory/router.js +387 -0
- package/lib/memory/typed-api.js +102 -0
- package/lib/memory-digest.js +195 -0
- package/lib/merge-rules.js +395 -0
- package/lib/migrate-dry-run.js +466 -0
- package/lib/orientation.js +863 -0
- package/lib/package-manager-remediation.js +103 -0
- package/lib/package-root.js +381 -0
- package/lib/patch-intent.js +890 -0
- package/lib/plugin-catalog.js +3 -4
- package/lib/plugin-manager.js +0 -5
- package/lib/pr-bundle.js +186 -0
- package/lib/pr-monitor/auto-actions.js +175 -0
- package/lib/pr-monitor/differ.js +195 -0
- package/lib/pr-monitor/digest.js +206 -0
- package/lib/pr-monitor/events.js +0 -0
- package/lib/pr-monitor/gather.js +124 -0
- package/lib/pr-monitor/journal.js +299 -0
- package/lib/pr-monitor/monitor.js +146 -0
- package/lib/pr-monitor/render-sticky.js +192 -0
- package/lib/pr-monitor/upsert-sticky.js +169 -0
- package/lib/pr-monitor/watch-lifecycle.js +95 -0
- package/lib/pr-monitor/watch.js +247 -0
- package/lib/pr-pull.js +1314 -0
- package/lib/pr-shepherd.js +494 -0
- package/lib/pr-state-validator.js +59 -0
- package/lib/preflight/gates.js +237 -0
- package/lib/preflight/runner.js +116 -0
- package/lib/project-discovery.js +0 -53
- package/lib/project-memory.js +99 -497
- package/lib/protected-path-manifest.js +281 -0
- package/lib/protected-state-surfaces.js +387 -0
- package/lib/release-readiness.js +2105 -0
- package/lib/reset.js +59 -45
- package/lib/review-adapter.js +68 -0
- package/lib/rules-sync.js +260 -0
- package/lib/runtime-health.js +241 -20
- package/lib/safety-config-renderer.js +268 -0
- package/lib/setup-action-log.js +1 -7
- package/lib/setup.js +27 -65
- package/lib/shell-utils.js +76 -6
- package/lib/skills-sync.js +330 -0
- package/lib/smart-status/scoring.js +17 -3
- package/lib/status/beads-snapshot.js +45 -2
- package/lib/status/presenter.js +169 -18
- package/lib/status/snapshot.js +186 -0
- package/lib/sync-backend.js +202 -0
- package/lib/untrusted-content.js +52 -0
- package/lib/upgrade-safety.js +251 -0
- package/lib/workflow/enforce-stage.js +351 -45
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +11 -22
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +37 -35
- package/rules/documentation.md +19 -0
- package/rules/kernel-tracking.md +26 -0
- package/rules/security.md +22 -0
- package/rules/tdd.md +20 -0
- package/rules/workflow.md +27 -0
- package/scripts/auto-backing-issue.js +47 -0
- package/scripts/beads-context.sh +81 -57
- package/scripts/beads-upgrade-smoke.sh +24 -3
- package/scripts/bootstrap-windows-tools.sh +78 -0
- package/scripts/branch-protection.js +2 -3
- package/scripts/check-agents.js +34 -137
- package/scripts/commitlint.js +3 -1
- package/scripts/conflict-detect.sh +3 -0
- package/scripts/dep-guard.sh +22 -3
- package/scripts/file-index.sh +3 -0
- package/scripts/forge-team/lib/claim.sh +34 -18
- package/scripts/forge-team/lib/dashboard.sh +61 -86
- package/scripts/forge-team/lib/epic.sh +99 -263
- package/scripts/forge-team/lib/hooks.sh +26 -28
- package/scripts/forge-team/lib/identity.sh +4 -4
- package/scripts/forge-team/lib/sync-github.sh +49 -84
- package/scripts/forge-team/lib/verify.sh +93 -83
- package/scripts/forge-team/lib/workload.sh +41 -65
- package/scripts/forge-team/tests/claim.test.sh +25 -19
- package/scripts/forge-team/tests/dashboard.test.sh +31 -46
- package/scripts/forge-team/tests/epic.test.sh +52 -71
- package/scripts/forge-team/tests/hooks.test.sh +38 -50
- package/scripts/forge-team/tests/identity.test.sh +3 -3
- package/scripts/forge-team/tests/integration.test.sh +44 -66
- package/scripts/forge-team/tests/sync-github.test.sh +50 -83
- package/scripts/forge-team/tests/verify.test.sh +37 -46
- package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
- package/scripts/forge-team/tests/workload.test.sh +32 -66
- package/scripts/gen-command-manifest.js +153 -0
- package/scripts/gen-embedded-assets.mjs +129 -0
- package/scripts/install.ps1 +139 -0
- package/scripts/install.sh +268 -0
- package/scripts/lib/release-asset.mjs +84 -0
- package/scripts/parity-check.mjs +145 -0
- package/scripts/parity-check.test.mjs +58 -0
- package/scripts/pin-agentic-workflow-images.js +112 -0
- package/scripts/pr-auto-actions.js +93 -0
- package/scripts/pr-coordinator.sh +3 -0
- package/scripts/pr-verdict-label.js +50 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +21 -94
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status.sh +60 -57
- package/scripts/spikes/config-race-bench.js +111 -0
- package/scripts/spikes/harness-capability-matrix.js +13 -0
- package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
- package/scripts/spikes/protected-path-manifest.js +20 -0
- package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
- package/scripts/sync-agent-skills.js +62 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +13 -6
- package/scripts/test.js +95 -12
- package/skills/claim-safety/SKILL.md +102 -0
- package/skills/claim-safety/evals/evals.json +46 -0
- package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
- package/skills/dev/evals/evals.json +50 -0
- package/skills/hermes-forge/SKILL.md +185 -0
- package/skills/hermes-forge/evals/evals.json +46 -0
- package/skills/issue-basics/SKILL.md +111 -0
- package/skills/issue-basics/evals/evals.json +46 -0
- package/skills/kernel/SKILL.md +166 -0
- package/skills/kernel/evals/evals.json +50 -0
- package/skills/memory/SKILL.md +102 -0
- package/skills/parallel-deep-research/SKILL.md +14 -11
- package/skills/parallel-deep-research/evals/evals.json +11 -27
- package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
- package/skills/plan/evals/evals.json +42 -0
- package/skills/research/SKILL.md +195 -0
- package/skills/research/evals/evals.json +42 -0
- package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
- package/skills/review/evals/evals.json +42 -0
- package/skills/rollback/SKILL.md +110 -0
- package/skills/rollback/evals/evals.json +46 -0
- package/skills/rollback/references/methods.md +204 -0
- package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
- package/skills/shepherd/SKILL.md +66 -0
- package/skills/shepherd/evals/evals.json +42 -0
- package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
- package/skills/ship/evals/evals.json +42 -0
- package/skills/smith/SKILL.md +142 -0
- package/skills/smith/evals/evals.json +46 -0
- package/skills/smith/references/autonomy-and-gates.md +94 -0
- package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
- package/skills/sonarcloud/evals/evals.json +46 -0
- package/skills/sonarcloud-analysis/SKILL.md +18 -13
- package/skills/sonarcloud-analysis/evals/evals.json +11 -15
- package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
- package/skills/status/evals/evals.json +50 -0
- package/skills/triage-ready/SKILL.md +121 -0
- package/skills/triage-ready/evals/evals.json +42 -0
- package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
- package/skills/validate/evals/evals.json +42 -0
- package/skills/verify/SKILL.md +299 -0
- package/skills/verify/evals/evals.json +50 -0
- package/.claude/commands/dev.md +0 -345
- package/.claude/commands/plan.md +0 -566
- package/.claude/commands/premerge.md +0 -186
- package/.claude/commands/research.md +0 -42
- package/.claude/commands/review.md +0 -451
- package/.claude/commands/rollback.md +0 -721
- package/.claude/commands/ship.md +0 -213
- package/.claude/commands/sonarcloud.md +0 -152
- package/.claude/commands/status.md +0 -90
- package/.claude/commands/validate.md +0 -288
- package/.claude/commands/verify.md +0 -269
- package/.claude/rules/workflow.md +0 -121
- package/.cline/workflows/dev.md +0 -342
- package/.cline/workflows/plan.md +0 -563
- package/.cline/workflows/premerge.md +0 -183
- package/.cline/workflows/research.md +0 -39
- package/.cline/workflows/review.md +0 -448
- package/.cline/workflows/rollback.md +0 -718
- package/.cline/workflows/ship.md +0 -210
- package/.cline/workflows/sonarcloud.md +0 -146
- package/.cline/workflows/status.md +0 -87
- package/.cline/workflows/validate.md +0 -285
- package/.cline/workflows/verify.md +0 -266
- package/.codex/config.toml +0 -11
- package/.codex/skills/dev/SKILL.md +0 -345
- package/.codex/skills/plan/SKILL.md +0 -566
- package/.codex/skills/premerge/SKILL.md +0 -186
- package/.codex/skills/research/SKILL.md +0 -42
- package/.codex/skills/review/SKILL.md +0 -451
- package/.codex/skills/rollback/SKILL.md +0 -721
- package/.codex/skills/ship/SKILL.md +0 -213
- package/.codex/skills/sonarcloud/SKILL.md +0 -149
- package/.codex/skills/status/SKILL.md +0 -90
- package/.codex/skills/validate/SKILL.md +0 -288
- package/.codex/skills/verify/SKILL.md +0 -269
- package/.cursor/commands/dev.md +0 -342
- package/.cursor/commands/plan.md +0 -563
- package/.cursor/commands/premerge.md +0 -183
- package/.cursor/commands/research.md +0 -39
- package/.cursor/commands/review.md +0 -448
- package/.cursor/commands/ship.md +0 -210
- package/.cursor/commands/sonarcloud.md +0 -146
- package/.cursor/commands/status.md +0 -87
- package/.cursor/commands/validate.md +0 -285
- package/.cursor/commands/verify.md +0 -266
- package/.cursorrules +0 -149
- package/.github/prompts/premerge.prompt.md +0 -188
- package/.github/prompts/research.prompt.md +0 -44
- package/.github/prompts/rollback.prompt.md +0 -723
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -89
- package/.github/workflows/github-to-beads.yml +0 -100
- package/.kilocode/workflows/dev.md +0 -346
- package/.kilocode/workflows/plan.md +0 -567
- package/.kilocode/workflows/premerge.md +0 -187
- package/.kilocode/workflows/research.md +0 -43
- package/.kilocode/workflows/review.md +0 -452
- package/.kilocode/workflows/rollback.md +0 -722
- package/.kilocode/workflows/ship.md +0 -214
- package/.kilocode/workflows/sonarcloud.md +0 -150
- package/.kilocode/workflows/status.md +0 -91
- package/.kilocode/workflows/validate.md +0 -289
- package/.kilocode/workflows/verify.md +0 -270
- package/.opencode/commands/dev.md +0 -345
- package/.opencode/commands/plan.md +0 -566
- package/.opencode/commands/premerge.md +0 -186
- package/.opencode/commands/research.md +0 -42
- package/.opencode/commands/review.md +0 -451
- package/.opencode/commands/rollback.md +0 -721
- package/.opencode/commands/ship.md +0 -213
- package/.opencode/commands/sonarcloud.md +0 -149
- package/.opencode/commands/status.md +0 -90
- package/.opencode/commands/validate.md +0 -288
- package/.opencode/commands/verify.md +0 -269
- package/.roo/commands/dev.md +0 -346
- package/.roo/commands/plan.md +0 -567
- package/.roo/commands/premerge.md +0 -187
- package/.roo/commands/research.md +0 -43
- package/.roo/commands/review.md +0 -452
- package/.roo/commands/rollback.md +0 -722
- package/.roo/commands/ship.md +0 -214
- package/.roo/commands/sonarcloud.md +0 -150
- package/.roo/commands/status.md +0 -91
- package/.roo/commands/validate.md +0 -289
- package/.roo/commands/verify.md +0 -270
- package/docs/BEADS_GITHUB_SYNC.md +0 -281
- package/docs/GREPTILE_SETUP.md +0 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
- package/docs/SETUP.md +0 -663
- package/docs/VALIDATION.md +0 -363
- package/lib/agents/cline.plugin.json +0 -29
- package/lib/agents/copilot.plugin.json +0 -24
- package/lib/agents/kilocode.plugin.json +0 -22
- package/lib/agents/opencode.plugin.json +0 -23
- package/lib/agents/roo.plugin.json +0 -30
- package/lib/beads-bootstrap.js +0 -225
- package/lib/beads-health-check.js +0 -188
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -584
- package/scripts/github-beads-sync/comment.mjs +0 -64
- package/scripts/github-beads-sync/config.mjs +0 -148
- package/scripts/github-beads-sync/github-api.mjs +0 -131
- package/scripts/github-beads-sync/index.mjs +0 -356
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -132
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
- package/scripts/github-beads-sync/run-bd.mjs +0 -161
- package/scripts/github-beads-sync/sanitize.mjs +0 -121
- package/scripts/github-beads-sync.config.json +0 -26
- package/scripts/sync-commands.js +0 -600
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Per-harness MCP config renderer.
|
|
5
|
+
*
|
|
6
|
+
* Renders a GENERIC MCP server descriptor into each harness's native MCP config,
|
|
7
|
+
* using read → merge → write (idempotent, preserves user/other servers). This
|
|
8
|
+
* replaces the old skip-if-exists behavior in setup, which silently refused to
|
|
9
|
+
* add a server whenever a config file already existed.
|
|
10
|
+
*
|
|
11
|
+
* Frozen descriptor interface (consumers build this shape; this module never
|
|
12
|
+
* references any specific server):
|
|
13
|
+
*
|
|
14
|
+
* {
|
|
15
|
+
* name: string, // server key
|
|
16
|
+
* transport: 'stdio' | 'http', // launch transport
|
|
17
|
+
* command: string, // executable (stdio) / launcher
|
|
18
|
+
* args: string[], // command arguments
|
|
19
|
+
* envRefs: Record<string, string>, // env var REFERENCES ('${VAR}') — never secrets
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* `envRefs` values MUST be `${VAR}` reference strings; literal secrets are rejected.
|
|
23
|
+
* Each harness expands them per its own semantics:
|
|
24
|
+
*
|
|
25
|
+
* - Claude : `.mcp.json` (JSON `mcpServers` map)
|
|
26
|
+
* - Cursor : `.cursor/mcp.json` (JSON `mcpServers` map)
|
|
27
|
+
* - Codex : `.codex/config.toml` (TOML `[mcp_servers.<name>]` tables)
|
|
28
|
+
*
|
|
29
|
+
* Dependency-free (no TOML lib) so it runs under `bun test` and the release gates.
|
|
30
|
+
*
|
|
31
|
+
* @module mcp-config-renderer
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const fs = require('node:fs');
|
|
35
|
+
const path = require('node:path');
|
|
36
|
+
|
|
37
|
+
const HARNESS_MCP_FILES = {
|
|
38
|
+
claude: '.mcp.json',
|
|
39
|
+
cursor: '.cursor/mcp.json',
|
|
40
|
+
codex: '.codex/config.toml',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const ENV_REF_PATTERN = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
|
|
44
|
+
|
|
45
|
+
/** Thrown when an existing config file cannot be parsed — signals "do not overwrite". */
|
|
46
|
+
class McpConfigParseError extends Error {
|
|
47
|
+
constructor(message, cause) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = 'McpConfigParseError';
|
|
50
|
+
this.cause = cause;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Validate + normalize a generic MCP server descriptor.
|
|
56
|
+
* @param {object} d
|
|
57
|
+
* @returns {{ name, transport, command, args, url, envRefs }}
|
|
58
|
+
*/
|
|
59
|
+
// MCP server names key an object entry and are written into JSON/TOML config, so
|
|
60
|
+
// restrict them to a safe identifier charset (no dots/quotes/whitespace that could
|
|
61
|
+
// break the TOML table header `[mcp_servers.<name>]` or collide on merge).
|
|
62
|
+
const MCP_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
63
|
+
|
|
64
|
+
// Extracted so validateDescriptor stays under the cognitive-complexity gate.
|
|
65
|
+
function validateEnvRefs(rawEnvRefs) {
|
|
66
|
+
const envRefs = rawEnvRefs && typeof rawEnvRefs === 'object' ? rawEnvRefs : {};
|
|
67
|
+
for (const [key, value] of Object.entries(envRefs)) {
|
|
68
|
+
if (typeof value !== 'string' || !ENV_REF_PATTERN.test(value)) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`MCP descriptor.envRefs.${key} must be a '\${VAR}' reference string, not a literal value`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return envRefs;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function validateDescriptor(d) {
|
|
78
|
+
if (!d || typeof d !== 'object') {
|
|
79
|
+
throw new Error('MCP descriptor must be an object');
|
|
80
|
+
}
|
|
81
|
+
if (!d.name || typeof d.name !== 'string') {
|
|
82
|
+
throw new Error('MCP descriptor.name is required');
|
|
83
|
+
}
|
|
84
|
+
if (!MCP_NAME_PATTERN.test(d.name)) {
|
|
85
|
+
throw new Error(`MCP descriptor.name must match ${MCP_NAME_PATTERN} (got '${d.name}')`);
|
|
86
|
+
}
|
|
87
|
+
const transport = d.transport || 'stdio';
|
|
88
|
+
if (transport !== 'stdio' && transport !== 'http') {
|
|
89
|
+
throw new Error(`MCP descriptor.transport must be 'stdio' or 'http' (got ${transport})`);
|
|
90
|
+
}
|
|
91
|
+
const command = typeof d.command === 'string' ? d.command : '';
|
|
92
|
+
const args = Array.isArray(d.args) ? d.args.map(String) : [];
|
|
93
|
+
const url = typeof d.url === 'string' ? d.url : '';
|
|
94
|
+
// stdio launches a process (command/args); http connects to a url. Enforce the
|
|
95
|
+
// field each transport needs so the frozen descriptor can represent both.
|
|
96
|
+
if (transport === 'http' && !url) {
|
|
97
|
+
throw new Error("MCP descriptor.url is required for transport 'http'");
|
|
98
|
+
}
|
|
99
|
+
if (transport === 'stdio' && !command) {
|
|
100
|
+
throw new Error("MCP descriptor.command is required for transport 'stdio'");
|
|
101
|
+
}
|
|
102
|
+
const envRefs = validateEnvRefs(d.envRefs);
|
|
103
|
+
return { name: d.name, transport, command, args, url, envRefs };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Build the JSON server entry (Claude + Cursor share the `mcpServers` schema). */
|
|
107
|
+
function toJsonServerEntry(descriptor) {
|
|
108
|
+
const d = validateDescriptor(descriptor);
|
|
109
|
+
const entry = {};
|
|
110
|
+
if (d.transport === 'http') {
|
|
111
|
+
entry.type = 'http';
|
|
112
|
+
entry.url = d.url;
|
|
113
|
+
} else {
|
|
114
|
+
if (d.command) entry.command = d.command;
|
|
115
|
+
if (d.args.length) entry.args = d.args;
|
|
116
|
+
}
|
|
117
|
+
if (Object.keys(d.envRefs).length) entry.env = { ...d.envRefs };
|
|
118
|
+
return entry;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Merge descriptors into an existing JSON MCP config string (read → merge → write).
|
|
123
|
+
* Preserves every server not named in `descriptors`.
|
|
124
|
+
* @param {string} existingText
|
|
125
|
+
* @param {object[]} descriptors
|
|
126
|
+
* @returns {string}
|
|
127
|
+
*/
|
|
128
|
+
function mergeJsonMcp(existingText, descriptors) {
|
|
129
|
+
let obj = {};
|
|
130
|
+
if (existingText && existingText.trim()) {
|
|
131
|
+
try {
|
|
132
|
+
obj = JSON.parse(existingText);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
// DATA-LOSS GUARD: never silently discard a populated-but-unparseable config
|
|
135
|
+
// (e.g. Cursor JSONC with comments/trailing commas). Signal the caller so it
|
|
136
|
+
// can back up and skip instead of overwriting the user's servers.
|
|
137
|
+
throw new McpConfigParseError('existing MCP config is not valid JSON', err);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) obj = {};
|
|
141
|
+
if (!obj.mcpServers || typeof obj.mcpServers !== 'object') obj.mcpServers = {};
|
|
142
|
+
for (const descriptor of descriptors) {
|
|
143
|
+
const d = validateDescriptor(descriptor);
|
|
144
|
+
obj.mcpServers[d.name] = toJsonServerEntry(d);
|
|
145
|
+
}
|
|
146
|
+
return JSON.stringify(obj, null, 2) + '\n';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function tomlString(value) {
|
|
150
|
+
return '"' + String(value).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function tomlArray(values) {
|
|
154
|
+
return '[' + values.map(tomlString).join(', ') + ']';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Render a single Codex `[mcp_servers.<name>]` TOML block (+ optional env table). */
|
|
158
|
+
function renderCodexServerBlock(descriptor) {
|
|
159
|
+
const d = validateDescriptor(descriptor);
|
|
160
|
+
const lines = [`[mcp_servers.${d.name}]`];
|
|
161
|
+
if (d.transport === 'http') {
|
|
162
|
+
lines.push(`url = ${tomlString(d.url)}`);
|
|
163
|
+
lines.push('transport = "http"');
|
|
164
|
+
} else {
|
|
165
|
+
if (d.command) lines.push(`command = ${tomlString(d.command)}`);
|
|
166
|
+
lines.push(`args = ${tomlArray(d.args)}`);
|
|
167
|
+
}
|
|
168
|
+
let block = lines.join('\n') + '\n';
|
|
169
|
+
const envKeys = Object.keys(d.envRefs);
|
|
170
|
+
if (envKeys.length) {
|
|
171
|
+
block += `\n[mcp_servers.${d.name}.env]\n`;
|
|
172
|
+
for (const key of envKeys) {
|
|
173
|
+
block += `${key} = ${tomlString(d.envRefs[key])}\n`;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return block;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Remove a TOML section (header line through the line before the next `[section]`). */
|
|
180
|
+
function stripTomlSection(text, header) {
|
|
181
|
+
const lines = String(text).split('\n');
|
|
182
|
+
const out = [];
|
|
183
|
+
let skipping = false;
|
|
184
|
+
for (const line of lines) {
|
|
185
|
+
const isHeader = line.trimStart().startsWith('[');
|
|
186
|
+
if (isHeader) {
|
|
187
|
+
if (line.trim() === header) {
|
|
188
|
+
skipping = true;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
skipping = false;
|
|
192
|
+
}
|
|
193
|
+
if (!skipping) out.push(line);
|
|
194
|
+
}
|
|
195
|
+
return out.join('\n');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Merge descriptors into an existing Codex `config.toml` string (read → merge →
|
|
200
|
+
* write). Only the targeted `[mcp_servers.<name>]` (+ `.env`) sections are
|
|
201
|
+
* replaced; all other config is preserved. Idempotent.
|
|
202
|
+
* @param {string} existingText
|
|
203
|
+
* @param {object[]} descriptors
|
|
204
|
+
* @returns {string}
|
|
205
|
+
*/
|
|
206
|
+
function mergeCodexToml(existingText, descriptors) {
|
|
207
|
+
let text = existingText || '';
|
|
208
|
+
for (const descriptor of descriptors) {
|
|
209
|
+
const d = validateDescriptor(descriptor);
|
|
210
|
+
text = stripTomlSection(text, `[mcp_servers.${d.name}]`);
|
|
211
|
+
text = stripTomlSection(text, `[mcp_servers.${d.name}.env]`);
|
|
212
|
+
}
|
|
213
|
+
const preamble = text.replace(/\s+$/, '');
|
|
214
|
+
let result = preamble ? preamble + '\n\n' : '';
|
|
215
|
+
result += descriptors.map(renderCodexServerBlock).join('\n');
|
|
216
|
+
return result.replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '') + '\n';
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Copy `filePath` to a stable `<file>.bak` (then numbered `.bak.1`, `.2`, …) so a
|
|
221
|
+
* repeated back-up never clobbers an earlier snapshot. Mirrors the AGENTS.md
|
|
222
|
+
* markerless-backup behavior in lib/commands/setup.js.
|
|
223
|
+
* @param {string} filePath
|
|
224
|
+
* @returns {string} the backup path written
|
|
225
|
+
*/
|
|
226
|
+
function backupFile(filePath) {
|
|
227
|
+
let backupPath = `${filePath}.bak`;
|
|
228
|
+
if (fs.existsSync(backupPath)) {
|
|
229
|
+
let suffix = 1;
|
|
230
|
+
while (fs.existsSync(`${filePath}.bak.${suffix}`)) suffix += 1;
|
|
231
|
+
backupPath = `${filePath}.bak.${suffix}`;
|
|
232
|
+
}
|
|
233
|
+
fs.copyFileSync(filePath, backupPath);
|
|
234
|
+
return backupPath;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Render (merge) MCP descriptors into one harness's native config on disk.
|
|
239
|
+
* Read → merge → write. If the existing file cannot be parsed, it is BACKED UP and
|
|
240
|
+
* left untouched (never overwritten) to avoid destroying user-defined servers.
|
|
241
|
+
*
|
|
242
|
+
* @param {object} params
|
|
243
|
+
* @param {'claude'|'cursor'|'codex'} params.harness
|
|
244
|
+
* @param {string} params.targetRoot - Project root.
|
|
245
|
+
* @param {object[]} params.descriptors - Generic MCP server descriptors.
|
|
246
|
+
* @returns {{ file: string, existed: boolean, skipped: boolean, backup?: string }}
|
|
247
|
+
*/
|
|
248
|
+
function renderMcpConfig({ harness, targetRoot, descriptors }) {
|
|
249
|
+
const rel = HARNESS_MCP_FILES[harness];
|
|
250
|
+
if (!rel) throw new Error(`Unknown MCP harness: ${harness}`);
|
|
251
|
+
const filePath = path.join(targetRoot, rel);
|
|
252
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
253
|
+
const existed = fs.existsSync(filePath);
|
|
254
|
+
const existing = existed ? fs.readFileSync(filePath, 'utf-8') : '';
|
|
255
|
+
|
|
256
|
+
let merged;
|
|
257
|
+
try {
|
|
258
|
+
merged = harness === 'codex'
|
|
259
|
+
? mergeCodexToml(existing, descriptors)
|
|
260
|
+
: mergeJsonMcp(existing, descriptors);
|
|
261
|
+
} catch (err) {
|
|
262
|
+
if (err instanceof McpConfigParseError && existed) {
|
|
263
|
+
const backup = backupFile(filePath);
|
|
264
|
+
console.warn(
|
|
265
|
+
` ⚠ ${rel} is not valid JSON (comments/trailing commas?) — left untouched to ` +
|
|
266
|
+
`avoid data loss. Backed up to ${path.basename(backup)}; add the MCP server manually.`,
|
|
267
|
+
);
|
|
268
|
+
return { file: filePath, existed, skipped: true, backup };
|
|
269
|
+
}
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
fs.writeFileSync(filePath, merged, 'utf-8');
|
|
274
|
+
return { file: filePath, existed, skipped: false };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
module.exports = {
|
|
278
|
+
HARNESS_MCP_FILES,
|
|
279
|
+
McpConfigParseError,
|
|
280
|
+
validateDescriptor,
|
|
281
|
+
toJsonServerEntry,
|
|
282
|
+
mergeJsonMcp,
|
|
283
|
+
renderCodexServerBlock,
|
|
284
|
+
mergeCodexToml,
|
|
285
|
+
stripTomlSection,
|
|
286
|
+
backupFile,
|
|
287
|
+
renderMcpConfig,
|
|
288
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module memory/graphiti-mcp
|
|
5
|
+
*
|
|
6
|
+
* DATA-ONLY descriptor for the `graphiti-memory` MCP server. This module does
|
|
7
|
+
* NOT write any file — it defines the harness-agnostic server descriptor shape
|
|
8
|
+
* so a per-harness MCP renderer can materialize it into the right place for
|
|
9
|
+
* each agent. `forge setup` does this today for Claude (`.mcp.json`) and Cursor
|
|
10
|
+
* (`.cursor/mcp.json`) via `lib/mcp-config-renderer.js` when the memory backend
|
|
11
|
+
* resolves to `graphiti`. Forge never speaks to Graphiti at runtime; agents
|
|
12
|
+
* do, over MCP.
|
|
13
|
+
*
|
|
14
|
+
* LOCKED interface (consumed by the parity agent's MCP renderer):
|
|
15
|
+
* { name, transport: 'stdio'|'http', command, args, envRefs }
|
|
16
|
+
* `envRefs` values are ALWAYS `${VAR}` reference strings — never literal keys or
|
|
17
|
+
* secrets — because each harness expands them differently and nothing sensitive
|
|
18
|
+
* may be baked into committed config.
|
|
19
|
+
*
|
|
20
|
+
* Design: docs/work/2026-07-06-graphiti-memory/research.md §1.7 / §2.2. The entry
|
|
21
|
+
* shape matches the Graphiti MCP server README (stdio transport, `uv run`).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Documented recommended defaults for a fresh opt-in (FalkorDB + OpenAI-compatible).
|
|
26
|
+
*
|
|
27
|
+
* CONSUMED TODAY by `buildGraphitiServerDescriptor`: `transport`, `command`,
|
|
28
|
+
* `mcpServerPath`, `graphDb`, `apiKeyEnv`.
|
|
29
|
+
*
|
|
30
|
+
* RESERVED for the fast-follow MCP wiring (the per-harness renderer that turns
|
|
31
|
+
* this descriptor into concrete env values) — `dbUri`, `neo4jUri`, `llmProvider`,
|
|
32
|
+
* `model`, `groupId` have NO EFFECT until then: the descriptor emits `${VAR}`
|
|
33
|
+
* references, not these literal values. They are kept here (and documented) so
|
|
34
|
+
* the shape is stable when the renderer lands; setting them now is a no-op.
|
|
35
|
+
*/
|
|
36
|
+
const DEFAULTS = Object.freeze({
|
|
37
|
+
transport: 'stdio', // 'stdio' | 'http' (consumed)
|
|
38
|
+
command: 'uv', // (consumed)
|
|
39
|
+
mcpServerPath: './graphiti/mcp_server', // (consumed)
|
|
40
|
+
graphDb: 'falkordb', // 'falkordb' | 'falkordb-lite' | 'neo4j' (consumed)
|
|
41
|
+
apiKeyEnv: 'OPENAI_API_KEY', // (consumed — emitted as ${OPENAI_API_KEY})
|
|
42
|
+
// --- reserved (no effect until the fast-follow MCP renderer) ---
|
|
43
|
+
dbUri: 'redis://localhost:6379', // documented default for the FalkorDB path
|
|
44
|
+
neo4jUri: 'bolt://localhost:7687',
|
|
45
|
+
llmProvider: 'openai',
|
|
46
|
+
model: 'gpt-5.5',
|
|
47
|
+
groupId: 'forge',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const SERVER_NAME = 'graphiti-memory';
|
|
51
|
+
|
|
52
|
+
/** Build a `${VAR}` reference string. */
|
|
53
|
+
function ref(name) {
|
|
54
|
+
return `\${${name}}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build the harness-agnostic Graphiti MCP server descriptor.
|
|
59
|
+
*
|
|
60
|
+
* @param {object} [config] - Partial override of DEFAULTS (graphDb, apiKeyEnv,
|
|
61
|
+
* mcpServerPath, transport, ...). Concrete secret/URI VALUES are never placed
|
|
62
|
+
* here — only which env vars the server needs, as `${VAR}` references.
|
|
63
|
+
* @returns {{ name: string, transport: string, command: string, args: string[], envRefs: Object<string,string> }}
|
|
64
|
+
*/
|
|
65
|
+
function buildGraphitiServerDescriptor(config = {}) {
|
|
66
|
+
const c = { ...DEFAULTS, ...config };
|
|
67
|
+
|
|
68
|
+
const args = [
|
|
69
|
+
'run',
|
|
70
|
+
'--isolated',
|
|
71
|
+
'--directory',
|
|
72
|
+
c.mcpServerPath,
|
|
73
|
+
'--project',
|
|
74
|
+
'.',
|
|
75
|
+
'main.py',
|
|
76
|
+
'--transport',
|
|
77
|
+
c.transport,
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const envRefs = {};
|
|
81
|
+
if (c.graphDb === 'neo4j') {
|
|
82
|
+
envRefs.NEO4J_URI = ref('NEO4J_URI');
|
|
83
|
+
envRefs.NEO4J_USER = ref('NEO4J_USER');
|
|
84
|
+
envRefs.NEO4J_PASSWORD = ref('NEO4J_PASSWORD');
|
|
85
|
+
} else {
|
|
86
|
+
envRefs.FALKORDB_URI = ref('FALKORDB_URI');
|
|
87
|
+
}
|
|
88
|
+
// LLM key referenced by env-var NAME only — never inlined.
|
|
89
|
+
envRefs[c.apiKeyEnv] = ref(c.apiKeyEnv);
|
|
90
|
+
envRefs.MODEL_NAME = ref('MODEL_NAME');
|
|
91
|
+
envRefs.GROUP_ID = ref('GRAPHITI_GROUP_ID');
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
name: SERVER_NAME,
|
|
95
|
+
transport: c.transport,
|
|
96
|
+
command: c.command,
|
|
97
|
+
args,
|
|
98
|
+
envRefs,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
DEFAULTS,
|
|
104
|
+
SERVER_NAME,
|
|
105
|
+
buildGraphitiServerDescriptor,
|
|
106
|
+
};
|