Files
msd-core/package.json
Tom Boucher 895d9df96d fix(#3477): run untrusted key_links patterns on a linear-time engine (#3496)
`cmdVerifyKeyLinks` compiled `must_haves.key_links[].pattern` from plan frontmatter with `new RegExp()` and tested it against whole file contents, so a nested-quantifier pattern such as `(a+)+$` hung `verify-phase` indefinitely (CWE-1333). JavaScript has no regex-execution timeout.

Untrusted patterns now run on RE2 (re2js), whose match time is linear in input length — the class is closed by the engine, not by a heuristic screen. The screen lost in the ADR-0174 consolidation was deliberately NOT restored: it never worked, since `(a|a)*$`, `((a+))+$`, `(a+){2,}$` and `(a{1,3})+$` all evade it. A refused pattern's matcher returns false for every input, so it cannot report a match no matter what the caller does.

The engine is vendored at gsd-core/bin/lib/vendor/re2js.cjs because gsd-core/bin/** is copied into installed trees with no node_modules; runtime dependencies are unchanged. New ESLint rule local/no-external-require-in-bin enforces that invariant, which had been documented in a comment since the #3024/#2071 bug class and enforced nowhere.

Backreferences and look-around are unsupported by RE2 by construction — disclosed in a Changed changeset.

Closes #3477

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 14:34:36 -04:00

157 lines
9.0 KiB
JSON

{
"name": "@opengsd/gsd-core",
"version": "1.10.0",
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"main": ".opencode/plugins/gsd-core.js",
"bin": {
"gsd-core": "bin/install.js",
"gsd-tools": "gsd-core/bin/gsd-tools.cjs",
"gsd_run": "gsd-core/bin/gsd_run",
"gsd-mcp-server": "bin/gsd-mcp-server.js"
},
"files": [
"bin",
"commands",
"skills",
"gsd-core",
"assets",
"agents",
".claude-plugin",
".opencode",
"GEMINI.md",
"hooks",
"scripts",
"!scripts/gen-emitted-baseline.cjs",
"!scripts/qa-smell-ratchet.cjs",
"!scripts/live-config-guard.cjs",
"!scripts/run-tests.cjs",
"!scripts/affected-tests-lib.cjs",
"!scripts/run-affected-tests.cjs",
"!scripts/lint-no-adhoc-regex-escape.cjs",
"pi",
"vscode"
],
"keywords": [
"claude",
"claude-code",
"ai",
"meta-prompting",
"context-engineering",
"spec-driven-development",
"codex",
"codex-cli"
],
"author": "OpenGSD",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/open-gsd/gsd-core.git"
},
"homepage": "https://github.com/open-gsd/gsd-core",
"bugs": {
"url": "https://github.com/open-gsd/gsd-core/issues"
},
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=24.0.0",
"npm": ">=10.0.0"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.84",
"ws": "^8.21.0"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
"@stryker-mutator/core": "^9.6.1",
"@types/node": "^22.19.19",
"c8": "^11.0.0",
"eslint": "^9.39.4",
"eslint-plugin-n": "^17.24.0",
"eslint-plugin-no-only-tests": "^3.4.0",
"espree": "^10.4.0",
"fast-check": "^4.8.0",
"globals": "^16.5.0",
"js-yaml": "^4.3.1",
"re2js": "^2.8.6",
"typescript": "^6.0.3",
"typescript-eslint": "^8.60.0"
},
"overrides": {
"qs": ">=6.15.2",
"body-parser": ">=2.3.0",
"@hono/node-server": ">=2.0.5"
},
"optionalDependencies": {
"fallow": "^2.70.0"
},
"scripts": {
"sync:launcher": "node scripts/sync-runtime-launcher.cjs",
"check:env": "node scripts/check-env.cjs",
"check:alias-drift": "node scripts/check-alias-drift.cjs",
"check:identity-drift": "node scripts/lint-package-identity-drift.cjs",
"check:phase-id-drift": "node scripts/lint-phase-id-drift.cjs",
"check:integrity": "node scripts/check-npm-integrity.cjs",
"build": "npm run generate:identity && npm run build:lib && npm run gen:section-manifest && npm run gen:context-index && npm run gen:plugin-skills && npm run gen:loop-host-contract && npm run gen:capability-registry && npm run build:hooks",
"build:hooks": "node scripts/build-hooks.js",
"build:lib": "tsc -p tsconfig.build.json",
"generate:identity": "node scripts/generate-package-identity.cjs",
"gen:context-index": "node scripts/gen-context-index.cjs --write",
"gen:loop-host-contract": "node scripts/gen-loop-host-contract.cjs --write",
"gen:plugin-skills": "node scripts/gen-plugin-skills.cjs --write",
"gen:capability-registry": "node scripts/gen-capability-registry.cjs --write",
"gen:registry": "node scripts/gen-registry.cjs --write",
"gen:install-tree": "node scripts/gen-install-tree-fixtures.cjs",
"gen:section-manifest": "node scripts/gen-section-manifest.cjs --write",
"regen:derived": "npm run build && npm run gen:registry && node scripts/gen-adr-index.cjs --write && node scripts/gen-capability-matrix.cjs --write && node scripts/gen-inventory-manifest.cjs --write && node scripts/gen-context-index.cjs --write && npm run gen:section-manifest && node scripts/sync-manifest-versions.cjs && npm run gen:install-tree",
"validate:registry": "node scripts/validate-registry.cjs",
"prepack": "npm run build:lib",
"prepare": "npm run build:lib",
"version": "node scripts/sync-manifest-versions.cjs --stage && node scripts/gen-capability-registry.cjs --write && git add gsd-core/bin/lib/capability-registry.cjs",
"prepublishOnly": "npm run build:lib && npm run build:hooks",
"pretest": "npm run build:lib && npm run lint:skill-deps",
"pretest:coverage": "npm run build:lib && npm run lint:skill-deps",
"lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings 0",
"lint:fix": "eslint . --fix",
"lint:table-schema-drift": "node scripts/lint-table-schema-drift.cjs",
"lint:frontmatter-scalar-broad-grep": "node scripts/lint-frontmatter-scalar-broad-grep.cjs",
"lint:removed-but-needed": "node scripts/lint-removed-but-needed.cjs",
"lint:ci": "npm run lint && npm run lint:skill-deps && npm run lint:generated-sync && node scripts/lint-test-file-count.cjs && node scripts/lint-command-contract.cjs && node scripts/lint-pr-check-project-dir.cjs && npm run lint:legacy-name && node scripts/lint-regression-test-names.cjs && node scripts/lint-allow-test-rule-refs.cjs && node scripts/lint-resolution-provenance.cjs && node scripts/lint-emitted-drift-ack.cjs && node scripts/lint-portable-timeout.cjs && node scripts/validate-registry.cjs && node scripts/lint-table-schema-drift.cjs && node scripts/lint-fix-has-regression-test.cjs && node scripts/lint-example-parser-parity.cjs && node scripts/lint-docs-command-form.cjs && node scripts/lint-plan-count-drift.cjs && node scripts/lint-milestone-window-drift.cjs && node scripts/lint-phase-enumeration-drift.cjs && node scripts/lint-planning-prompt-drift.cjs && node scripts/lint-completion-ratio-drift.cjs && node scripts/lint-state-field-drift.cjs && node scripts/lint-state-write-path-drift.cjs && node scripts/lint-completion-predicate-drift.cjs && node scripts/lint-planning-snapshot-bypass-drift.cjs && node scripts/lint-health-diagnostic-rule-table.cjs && node scripts/lint-planning-artifact-writer-drift.cjs && node scripts/lint-frontmatter-scalar-broad-grep.cjs && node scripts/lint-removed-but-needed.cjs && node scripts/lint-no-adhoc-regex-escape.cjs && node scripts/lint-vendored-deps.cjs",
"lint:allow-test-rule-refs": "node scripts/lint-allow-test-rule-refs.cjs",
"lint:regression-names": "node scripts/lint-regression-test-names.cjs",
"lint:descriptions": "node scripts/lint-descriptions.cjs",
"lint:skill-deps": "node scripts/lint-skill-deps.cjs",
"lint:test-file-count": "node scripts/lint-test-file-count.cjs",
"lint:pr-checks": "node scripts/lint-pr-check-project-dir.cjs",
"lint:changeset": "node scripts/changeset/lint.cjs",
"lint:generated-sync": "node scripts/gen-capability-registry.cjs --check && node scripts/gen-loop-host-contract.cjs --check && node scripts/gen-capability-matrix.cjs --check && node scripts/sync-manifest-versions.cjs --check && node scripts/gen-inventory-manifest.cjs --check && node scripts/generate-package-identity.cjs --check && node scripts/gen-plugin-skills.cjs --check && node scripts/gen-registry.cjs --check && node scripts/gen-adr-index.cjs --check && node scripts/check-glossary-refs.cjs --check && node scripts/lint-compiled-artifact-sync.cjs --check && node scripts/gen-context-index.cjs --check && node scripts/gen-section-manifest.cjs --check && node scripts/gen-health-docs.cjs --check",
"lint:docs": "node scripts/lint-docs-required.cjs",
"lint:qa-smells": "node scripts/qa-smell-ratchet.cjs",
"lint:legacy-name": "node scripts/lint-legacy-dir-name.cjs",
"lint:docs-command-form": "node scripts/lint-docs-command-form.cjs",
"ci:test-scope": "node scripts/ci-test-scope.cjs",
"changeset": "node scripts/changeset/new.cjs",
"changelog:render": "node scripts/changeset/cli.cjs render",
"test": "node scripts/run-tests.cjs",
"test:unit": "node scripts/run-tests.cjs --suite unit",
"test:integration": "node scripts/run-tests.cjs --suite integration",
"test:install": "node scripts/run-tests.cjs --suite install",
"test:security": "node scripts/run-tests.cjs --suite security",
"test:slow": "node scripts/run-tests.cjs --suite slow",
"test:qa": "node scripts/run-tests.cjs --suite qa",
"test:affected": "node scripts/run-affected-tests.cjs",
"test:coverage": "c8 --check-coverage --lines 70 --branches 60 --reporter text --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs",
"test:coverage:scripts-floor": "c8 check-coverage --lines 55 --include 'scripts/**/*.cjs' --exclude 'tests/**' --all",
"test:coverage:unit": "c8 --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs --suite unit && node scripts/check-coverage-gate.cjs",
"test:coverage:unit:raw": "c8 --reporter none node scripts/run-tests.cjs --suite unit",
"test:coverage:report": "c8 report --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all && node scripts/check-coverage-gate.cjs",
"test:coverage:all": "npm run test:coverage",
"test:mutation": "stryker run",
"test:mutation:since": "stryker run --incremental --since origin/next"
},
"allowScripts": {
"fallow@2.70.0": true
}
}