UNPKG

paqad-ai

Version:

Spec-driven development framework — AI agents that think before they type

443 lines (433 loc) • 12.9 kB
import { createRequire as __paqadCreateRequire } from 'module'; const require = __paqadCreateRequire(import.meta.url); import { PATHS } from "./chunk-IHMBVS6H.js"; import { init_esm_shims } from "./chunk-IDFRWBMN.js"; // node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs init_esm_shims(); var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { if (!input) { return input; } return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } var _UNC_REGEX = /^[/\\]{2}/; var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; var _DRIVE_LETTER_RE = /^[A-Za-z]:$/; var _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; var _EXTNAME_RE = /.(\.[^./]+|\.)$/; var normalize = function(path) { if (path.length === 0) { return "."; } path = normalizeWindowsPath(path); const isUNCPath = path.match(_UNC_REGEX); const isPathAbsolute = isAbsolute(path); const trailingSeparator = path[path.length - 1] === "/"; path = normalizeString(path, !isPathAbsolute); if (path.length === 0) { if (isPathAbsolute) { return "/"; } return trailingSeparator ? "./" : "."; } if (trailingSeparator) { path += "/"; } if (_DRIVE_LETTER_RE.test(path)) { path += "/"; } if (isUNCPath) { if (!isPathAbsolute) { return `//./${path}`; } return `//${path}`; } return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; }; var join = function(...segments) { let path = ""; for (const seg of segments) { if (!seg) { continue; } if (path.length > 0) { const pathTrailing = path[path.length - 1] === "/"; const segLeading = seg[0] === "/"; const both = pathTrailing && segLeading; if (both) { path += seg.slice(1); } else { path += pathTrailing || segLeading ? seg : `/${seg}`; } } else { path += seg; } } return normalize(path); }; function cwd() { if (typeof process !== "undefined" && typeof process.cwd === "function") { return process.cwd().replace(/\\/g, "/"); } return "/"; } var resolve = function(...arguments_) { arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); let resolvedPath = ""; let resolvedAbsolute = false; for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { const path = index >= 0 ? arguments_[index] : cwd(); if (!path || path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = isAbsolute(path); } resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute && !isAbsolute(resolvedPath)) { return `/${resolvedPath}`; } return resolvedPath.length > 0 ? resolvedPath : "."; }; function normalizeString(path, allowAboveRoot) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let char = null; for (let index = 0; index <= path.length; ++index) { if (index < path.length) { char = path[index]; } else if (char === "/") { break; } else { char = "/"; } if (char === "/") { if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = index; dots = 0; continue; } else if (res.length > 0) { res = ""; lastSegmentLength = 0; lastSlash = index; dots = 0; continue; } } if (allowAboveRoot) { res += res.length > 0 ? "/.." : ".."; lastSegmentLength = 2; } } else { if (res.length > 0) { res += `/${path.slice(lastSlash + 1, index)}`; } else { res = path.slice(lastSlash + 1, index); } lastSegmentLength = index - lastSlash - 1; } lastSlash = index; dots = 0; } else if (char === "." && dots !== -1) { ++dots; } else { dots = -1; } } return res; } var isAbsolute = function(p) { return _IS_ABSOLUTE_RE.test(p); }; var extname = function(p) { if (p === "..") return ""; const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); return match && match[1] || ""; }; var relative = function(from, to) { const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { return _to.join("/"); } const _fromCopy = [..._from]; for (const segment of _fromCopy) { if (_to[0] !== segment) { break; } _from.shift(); _to.shift(); } return [..._from.map(() => ".."), ..._to].join("/"); }; var dirname = function(p) { const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { segments[0] += "/"; } return segments.join("/") || (isAbsolute(p) ? "/" : "."); }; var basename = function(p, extension) { const segments = normalizeWindowsPath(p).split("/"); let lastSegment = ""; for (let i = segments.length - 1; i >= 0; i--) { const val = segments[i]; if (val) { lastSegment = val; break; } } return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; }; // node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.mjs init_esm_shims(); // src/core/ids/ulid.ts init_esm_shims(); import { randomBytes } from "crypto"; var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; var ENCODING_LEN = ENCODING.length; var TIME_LEN = 10; var RANDOM_LEN = 16; var ULID_BODY = `[0-9A-HJKMNP-TV-Z]{${TIME_LEN + RANDOM_LEN}}`; var lastTime = -1; var lastRandom = []; function encodeTime(time) { let remainder = time; let out = ""; for (let i = TIME_LEN - 1; i >= 0; i--) { const mod = remainder % ENCODING_LEN; out = ENCODING[mod] + out; remainder = (remainder - mod) / ENCODING_LEN; } return out; } function randomIndices() { const bytes = randomBytes(RANDOM_LEN); return Array.from(bytes, (byte) => byte % ENCODING_LEN); } function incrementIndices(indices) { const next = [...indices]; for (let i = next.length - 1; i >= 0; i--) { if (next[i] < ENCODING_LEN - 1) { next[i] = next[i] + 1; return next; } next[i] = 0; } return randomIndices(); } function ulid(seedTime = Date.now()) { if (seedTime <= lastTime) { lastRandom = incrementIndices(lastRandom); } else { lastTime = seedTime; lastRandom = randomIndices(); } return encodeTime(seedTime) + lastRandom.map((index) => ENCODING[index]).join(""); } // src/planning/slug-utils.ts init_esm_shims(); // src/core/text/trim-char.ts init_esm_shims(); function trimLeadingChar(value, char) { let start = 0; while (start < value.length && value[start] === char) start += 1; return start === 0 ? value : value.slice(start); } function trimTrailingChar(value, char) { let end = value.length; while (end > 0 && value[end - 1] === char) end -= 1; return end === value.length ? value : value.slice(0, end); } function trimChar(value, char) { return trimTrailingChar(trimLeadingChar(value, char), char); } function slugifyAscii(value) { return trimChar(value.toLowerCase().replace(/[^a-z0-9]+/g, "-"), "-"); } // src/planning/slug-utils.ts var MAX_SLUG_LENGTH = 80; function deriveSlug(featureId, requestText) { const source = [featureId, requestText].filter(Boolean).join(" "); const normalized = slugifyAscii(source); if (!normalized) { return "planning-manifest"; } return trimTrailingChar(normalized.slice(0, MAX_SLUG_LENGTH), "-") || "planning-manifest"; } function isSlugSafe(slug) { return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug); } // src/feature-evidence/paths.ts init_esm_shims(); var FEATURE_BUNDLE_FILES = { feature: "feature.json", plan: "plan.json", specification: "specification.json", review: "review.json", stageEvidence: "stage-evidence.jsonl", ruleRun: "rule-run.jsonl", rulesLoaded: "rules-loaded.json", delivery: "delivery.json", receipt: "receipt.json", aiBom: "ai-bom.json", rag: "rag.jsonl", checks: "checks.json", duplication: "duplication.jsonl", changeMetrics: "change-metrics.jsonl", evidence: "evidence.jsonl", visualEvidence: "visual-evidence.json", specMd: "spec.md", request: "request.md", clarification: "clarification.json", experts: "experts.json", highTable: "high-table.jsonl", cost: "cost.json", decisions: "decisions.json", techDebt: "tech-debt.json", ruleOverrides: "rule-overrides.jsonl", fixProof: "fix-proof.json", hld: "hld.json", hldMd: "hld.md" }; var LEGACY_BUNDLE_FILES = { specificationMd: "specification.md", contextEfficiency: "context-efficiency.jsonl" }; var SCREENSHOTS_DIR = "screenshots"; var JIRA_ISSUE = "[A-Z][A-Z0-9]*-\\d+"; var GITHUB_ISSUE = "\\d+"; var DIR_NAME_RE = new RegExp( `^(?:(${JIRA_ISSUE}|${GITHUB_ISSUE})-)?([a-z0-9]+(?:-[a-z0-9]+)*)-(${ULID_BODY})$` ); var ISSUE_RE = new RegExp(`^(?:${JIRA_ISSUE}|${GITHUB_ISSUE})$`); function featureDir(dirName) { return join(PATHS.FEATURE_EVIDENCE_DIR, dirName); } function featureChangeKey(dirName) { return parseFeatureDirName(dirName)?.ulid ?? dirName; } function featureFilePath(dirName, file) { return join(featureDir(dirName), FEATURE_BUNDLE_FILES[file]); } function featureReportPath(dirName) { return join(featureDir(dirName), "report.html"); } function featureScreenshotsDir(dirName) { return join(featureDir(dirName), SCREENSHOTS_DIR); } function featureLegacySpecMarkdownPath(dirName) { return join(featureDir(dirName), LEGACY_BUNDLE_FILES.specificationMd); } function featureSessionControlPath(sessionId) { return join(PATHS.FEATURE_EVIDENCE_SESSION_DIR, `${sessionId}.json`); } function chatDir(sessionId) { return join(PATHS.CHAT_LEDGER_DIR, sessionId); } function chatRagPath(sessionId) { return join(chatDir(sessionId), FEATURE_BUNDLE_FILES.rag); } function formatFeatureDirName(parts) { if (!isSlugSafe(parts.slug)) { throw new Error(`Unsafe feature slug: ${JSON.stringify(parts.slug)}`); } if (!new RegExp(`^${ULID_BODY}$`).test(parts.ulid)) { throw new Error(`Malformed feature ULID: ${JSON.stringify(parts.ulid)}`); } if (parts.issue !== null && !ISSUE_RE.test(parts.issue)) { throw new Error(`Malformed feature issue ref: ${JSON.stringify(parts.issue)}`); } const prefix = parts.issue ? `${parts.issue}-` : ""; return `${prefix}${parts.slug}-${parts.ulid}`; } function parseFeatureDirName(dirName) { const match = DIR_NAME_RE.exec(dirName); if (!match) { return null; } return { issue: match[1] ?? null, slug: match[2], ulid: match[3] }; } function isFeatureDirName(dirName) { return parseFeatureDirName(dirName) !== null; } // src/feature-evidence/types.ts init_esm_shims(); var FEATURE_DOC_TYPE = "paqad.feature"; var PLAN_DOC_TYPE = "paqad.plan"; var REVIEW_DOC_TYPE = "paqad.review"; var SPECIFICATION_DOC_TYPE = "paqad.specification"; var SPEC_SOURCE_DOC_TYPE = "paqad.spec"; var REQUEST_DOC_TYPE = "paqad.request"; var CLARIFICATION_DOC_TYPE = "paqad.clarification"; var EXPERTS_DOC_TYPE = "paqad.experts"; var DECISIONS_DOC_TYPE = "paqad.decisions"; var TECH_DEBT_DOC_TYPE = "paqad.tech-debt"; var RULE_OVERRIDE_DOC_TYPE = "paqad.rule-override"; var FIX_PROOF_DOC_TYPE = "paqad.fix-proof"; var FEATURE_SESSION_DOC_TYPE = "paqad.feature-session"; var FEATURE_EVIDENCE_SCHEMA_VERSION = 1; var FEATURE_DOC_SCHEMA_VERSION = 2; export { normalize, join, resolve, isAbsolute, extname, relative, dirname, basename, ULID_BODY, ulid, trimTrailingChar, trimChar, slugifyAscii, deriveSlug, isSlugSafe, FEATURE_BUNDLE_FILES, LEGACY_BUNDLE_FILES, SCREENSHOTS_DIR, featureDir, featureChangeKey, featureFilePath, featureReportPath, featureScreenshotsDir, featureLegacySpecMarkdownPath, featureSessionControlPath, chatRagPath, formatFeatureDirName, parseFeatureDirName, isFeatureDirName, FEATURE_DOC_TYPE, PLAN_DOC_TYPE, REVIEW_DOC_TYPE, SPECIFICATION_DOC_TYPE, SPEC_SOURCE_DOC_TYPE, REQUEST_DOC_TYPE, CLARIFICATION_DOC_TYPE, EXPERTS_DOC_TYPE, DECISIONS_DOC_TYPE, TECH_DEBT_DOC_TYPE, RULE_OVERRIDE_DOC_TYPE, FIX_PROOF_DOC_TYPE, FEATURE_SESSION_DOC_TYPE, FEATURE_EVIDENCE_SCHEMA_VERSION, FEATURE_DOC_SCHEMA_VERSION };