feat(sdk): Phase 1 typed query foundation (gsd-sdk query) (#2118)

* feat(sdk): add typed query foundation and gsd-sdk query (Phase 1)

Add sdk/src/query registry and handlers with tests, GSDQueryError, CLI query wiring, and supporting type/tool-scoping hooks. Update CHANGELOG. Vitest 4 constructor mock fixes in milestone-runner tests.

Made-with: Cursor

* chore: gitignore .cursor for local-only Cursor assets

Made-with: Cursor

* fix(sdk): harden query layer for PR review (paths, locks, CLI, ReDoS)

- resolvePathUnderProject: realpath + relative containment for frontmatter and key_links

- commitToSubrepo: path checks + sanitizeCommitMessage

- statePlannedPhase: readModifyWriteStateMd (lock); MUTATION_COMMANDS + events

- key_links: regexForKeyLinkPattern length/ReDoS guard; phase dirs: reject .. and separators

- gsd-sdk: strip --pick before parseArgs; strict parser; QueryRegistry.commands()

- progress: static GSDError import; tests updated

Made-with: Cursor

* feat(sdk): query follow-up — tests, QUERY-HANDLERS, registry, locks, intel depth

Made-with: Cursor

* docs(sdk): use ASCII punctuation in QUERY-HANDLERS.md

Made-with: Cursor
This commit is contained in:
Rezolv
2026-04-12 18:15:04 -04:00
committed by GitHub
parent 66a5f939b0
commit 6f79b1dd5e
36 changed files with 848 additions and 142 deletions

View File

@@ -18,7 +18,7 @@
* ```
*/
import { existsSync, readdirSync, statSync } from 'node:fs';
import { existsSync, readdirSync, statSync, type Dirent } from 'node:fs';
import { readFile } from 'node:fs/promises';
import { join, relative } from 'node:path';
import { homedir } from 'node:os';
@@ -90,9 +90,9 @@ export const initNewProject: QueryHandler = async (_args, projectDir) => {
function findCodeFiles(dir: string, depth: number): boolean {
if (depth > 3) return false;
let entries: Array<{ isDirectory(): boolean; isFile(): boolean; name: string }>;
let entries: Dirent[];
try {
entries = readdirSync(dir, { withFileTypes: true }) as unknown as Array<{ isDirectory(): boolean; isFile(): boolean; name: string }>;
entries = readdirSync(dir, { withFileTypes: true });
} catch {
return false;
}
@@ -202,7 +202,7 @@ export const initProgress: QueryHandler = async (_args, projectDir) => {
// Scan phase directories
try {
const entries = readdirSync(paths.phases, { withFileTypes: true });
const dirs = (entries as unknown as Array<{ isDirectory(): boolean; name: string }>)
const dirs = entries
.filter(e => e.isDirectory())
.map(e => e.name)
.sort((a, b) => {
@@ -339,7 +339,7 @@ export const initManager: QueryHandler = async (_args, projectDir) => {
// Pre-compute directory listing once
let phaseDirEntries: string[] = [];
try {
phaseDirEntries = (readdirSync(paths.phases, { withFileTypes: true }) as unknown as Array<{ isDirectory(): boolean; name: string }>)
phaseDirEntries = readdirSync(paths.phases, { withFileTypes: true })
.filter(e => e.isDirectory())
.map(e => e.name);
} catch { /* intentionally empty */ }