paqad-ai 0.3.1 → 0.3.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/dist/cli/index.js +787 -283
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +509 -5
- package/dist/index.js +2827 -507
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -73,6 +73,10 @@ var init_paths = __esm({
|
|
|
73
73
|
// Feature 2 - Predictive Cache
|
|
74
74
|
TRANSITION_LOG: ".paqad/cache/transition-log.json",
|
|
75
75
|
CACHE_METRICS: ".paqad/cache/metrics.json",
|
|
76
|
+
PLANNING_SPECS_DIR: ".paqad/specs",
|
|
77
|
+
PLANNING_MODULE_HEALTH_DIR: ".paqad/module-health",
|
|
78
|
+
COMPILED_RULES: ".paqad/compiled-rules.json",
|
|
79
|
+
PLANNING_COSTS: ".paqad/cache/planning-costs.json",
|
|
76
80
|
// Feature 3 - Context Budget Optimizer
|
|
77
81
|
CONTEXT_BUDGET_STATE: ".paqad/session/context-budget.json",
|
|
78
82
|
CONTEXT_SAVINGS: ".paqad/session/context-savings.json",
|
|
@@ -283,7 +287,7 @@ var init_domain = __esm({
|
|
|
283
287
|
"node-service",
|
|
284
288
|
"short-video"
|
|
285
289
|
];
|
|
286
|
-
ACTIVE_CAPABILITIES = ["content", "coding", "security"];
|
|
290
|
+
ACTIVE_CAPABILITIES = ["content", "coding", "planning", "security"];
|
|
287
291
|
DOMAIN_STACK_MAP = {
|
|
288
292
|
coding: [
|
|
289
293
|
"laravel",
|
|
@@ -1163,6 +1167,19 @@ var init_onboarding_manifest_schema = __esm({
|
|
|
1163
1167
|
executable: { type: "boolean" }
|
|
1164
1168
|
}
|
|
1165
1169
|
}
|
|
1170
|
+
},
|
|
1171
|
+
planning_artifacts: {
|
|
1172
|
+
type: "object",
|
|
1173
|
+
additionalProperties: false,
|
|
1174
|
+
required: ["compiled_rules_path", "module_health_initialized"],
|
|
1175
|
+
properties: {
|
|
1176
|
+
compiled_rules_path: { type: "string" },
|
|
1177
|
+
classifier_config_path: { type: "string" },
|
|
1178
|
+
module_health_initialized: {
|
|
1179
|
+
type: "array",
|
|
1180
|
+
items: { type: "string" }
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1166
1183
|
}
|
|
1167
1184
|
}
|
|
1168
1185
|
};
|
|
@@ -4261,20 +4278,20 @@ async function readIgnoreRules(projectRoot, config) {
|
|
|
4261
4278
|
}
|
|
4262
4279
|
return rules;
|
|
4263
4280
|
}
|
|
4264
|
-
function isEligibleByLayer1(
|
|
4265
|
-
const lowerBasename =
|
|
4281
|
+
function isEligibleByLayer1(basename12, extAllowlist, basenameIncludes) {
|
|
4282
|
+
const lowerBasename = basename12.toLowerCase();
|
|
4266
4283
|
for (const extension of extAllowlist) {
|
|
4267
4284
|
if (lowerBasename.endsWith(extension.toLowerCase())) {
|
|
4268
4285
|
return true;
|
|
4269
4286
|
}
|
|
4270
4287
|
}
|
|
4271
|
-
if (basenameIncludes.has(
|
|
4288
|
+
if (basenameIncludes.has(basename12)) {
|
|
4272
4289
|
return true;
|
|
4273
4290
|
}
|
|
4274
|
-
const stem =
|
|
4291
|
+
const stem = basename12.split(".")[0];
|
|
4275
4292
|
return stem.length > 0 && basenameIncludes.has(stem);
|
|
4276
4293
|
}
|
|
4277
|
-
function isExcludedByLayer2(absolutePath,
|
|
4294
|
+
function isExcludedByLayer2(absolutePath, basename12, projectRoot, hardExclusions, adapterFiles) {
|
|
4278
4295
|
const relativePath = toProjectRelativePath(projectRoot, absolutePath);
|
|
4279
4296
|
const segments = splitSegments(relativePath);
|
|
4280
4297
|
if (relativePath.startsWith(".paqad/") || segments.includes(".paqad")) {
|
|
@@ -4284,8 +4301,8 @@ function isExcludedByLayer2(absolutePath, basename9, projectRoot, hardExclusions
|
|
|
4284
4301
|
if (aiToolDir) {
|
|
4285
4302
|
return `ai-tool-directory:${aiToolDir}`;
|
|
4286
4303
|
}
|
|
4287
|
-
if (hardExclusions.has(
|
|
4288
|
-
return adapterFiles.has(
|
|
4304
|
+
if (hardExclusions.has(basename12)) {
|
|
4305
|
+
return adapterFiles.has(basename12) ? `adapter-file:${basename12}` : `hard-file:${basename12}`;
|
|
4289
4306
|
}
|
|
4290
4307
|
return void 0;
|
|
4291
4308
|
}
|
|
@@ -4304,8 +4321,8 @@ function findMatchingDirectory(relativePath, directories) {
|
|
|
4304
4321
|
return relativeDir === normalized || relativeDir.startsWith(`${normalized}/`) || relativeDir.includes(`/${normalized}/`) || relativeDir.endsWith(`/${normalized}`);
|
|
4305
4322
|
});
|
|
4306
4323
|
}
|
|
4307
|
-
function isSoftEnvExcluded(
|
|
4308
|
-
return
|
|
4324
|
+
function isSoftEnvExcluded(basename12) {
|
|
4325
|
+
return basename12 === ".env" || basename12.startsWith(".env.");
|
|
4309
4326
|
}
|
|
4310
4327
|
function resolveIgnorePattern(baseDir, pattern) {
|
|
4311
4328
|
const normalizedBase = trimSlashes(toPosixPath(baseDir));
|
|
@@ -4635,9 +4652,9 @@ var init_file_filter = __esm({
|
|
|
4635
4652
|
return this.discoverFiles();
|
|
4636
4653
|
}
|
|
4637
4654
|
async evaluateFile(absolutePath, layer3IgnoreRules) {
|
|
4638
|
-
const
|
|
4655
|
+
const basename12 = basenameOf(absolutePath);
|
|
4639
4656
|
const relativePath = toProjectRelativePath(this.options.projectRoot, absolutePath);
|
|
4640
|
-
if (!isEligibleByLayer1(
|
|
4657
|
+
if (!isEligibleByLayer1(basename12, this.extensionAllowlist, this.namedBasenameIncludes)) {
|
|
4641
4658
|
return {
|
|
4642
4659
|
path: absolutePath,
|
|
4643
4660
|
excluded: true,
|
|
@@ -4647,7 +4664,7 @@ var init_file_filter = __esm({
|
|
|
4647
4664
|
}
|
|
4648
4665
|
const layer2 = isExcludedByLayer2(
|
|
4649
4666
|
absolutePath,
|
|
4650
|
-
|
|
4667
|
+
basename12,
|
|
4651
4668
|
this.options.projectRoot,
|
|
4652
4669
|
this.hardNamedFileExclusionSet,
|
|
4653
4670
|
this.adapterFileExclusionSet
|
|
@@ -4660,7 +4677,7 @@ var init_file_filter = __esm({
|
|
|
4660
4677
|
rule: layer2
|
|
4661
4678
|
};
|
|
4662
4679
|
}
|
|
4663
|
-
const layer3 = this.evaluateLayer3(relativePath,
|
|
4680
|
+
const layer3 = this.evaluateLayer3(relativePath, basename12, layer3IgnoreRules);
|
|
4664
4681
|
if (layer3) {
|
|
4665
4682
|
return {
|
|
4666
4683
|
path: absolutePath,
|
|
@@ -4683,7 +4700,7 @@ var init_file_filter = __esm({
|
|
|
4683
4700
|
excluded: false
|
|
4684
4701
|
};
|
|
4685
4702
|
}
|
|
4686
|
-
evaluateLayer3(relativePath,
|
|
4703
|
+
evaluateLayer3(relativePath, basename12, ignoreRules) {
|
|
4687
4704
|
const includedByConfig = this.ragConfig.include.some(
|
|
4688
4705
|
(pattern) => matchesProjectGlob(relativePath, pattern)
|
|
4689
4706
|
);
|
|
@@ -4708,7 +4725,7 @@ var init_file_filter = __esm({
|
|
|
4708
4725
|
if (configExclude && !includedByConfig) {
|
|
4709
4726
|
return `config-exclude:${configExclude}`;
|
|
4710
4727
|
}
|
|
4711
|
-
if (isSoftEnvExcluded(
|
|
4728
|
+
if (isSoftEnvExcluded(basename12) && !includedByConfig) {
|
|
4712
4729
|
return "soft-env-exclusion";
|
|
4713
4730
|
}
|
|
4714
4731
|
return void 0;
|
|
@@ -8211,6 +8228,15 @@ init_esm_shims();
|
|
|
8211
8228
|
// src/core/constants/index.ts
|
|
8212
8229
|
init_paths();
|
|
8213
8230
|
|
|
8231
|
+
// src/core/constants/planning.ts
|
|
8232
|
+
init_esm_shims();
|
|
8233
|
+
var HEALTH_TIERS = {
|
|
8234
|
+
STABLE: "stable",
|
|
8235
|
+
MODERATE: "moderate",
|
|
8236
|
+
FRAGILE: "fragile",
|
|
8237
|
+
UNKNOWN: "unknown"
|
|
8238
|
+
};
|
|
8239
|
+
|
|
8214
8240
|
// src/core/errors/index.ts
|
|
8215
8241
|
init_esm_shims();
|
|
8216
8242
|
|
|
@@ -8391,6 +8417,15 @@ init_esm_shims();
|
|
|
8391
8417
|
// src/core/types/pentest.ts
|
|
8392
8418
|
init_esm_shims();
|
|
8393
8419
|
|
|
8420
|
+
// src/core/types/planning.ts
|
|
8421
|
+
init_esm_shims();
|
|
8422
|
+
|
|
8423
|
+
// src/core/types/post-classification.ts
|
|
8424
|
+
init_esm_shims();
|
|
8425
|
+
|
|
8426
|
+
// src/core/types/pre-classification.ts
|
|
8427
|
+
init_esm_shims();
|
|
8428
|
+
|
|
8394
8429
|
// src/core/types/project-profile.ts
|
|
8395
8430
|
init_esm_shims();
|
|
8396
8431
|
|
|
@@ -10594,6 +10629,7 @@ var HealthChecker = class {
|
|
|
10594
10629
|
this.checkMcp(projectRoot, profile),
|
|
10595
10630
|
this.checkSkillCache(projectRoot),
|
|
10596
10631
|
this.checkContextHitRate(projectRoot, profile),
|
|
10632
|
+
this.checkClassificationOverrideRate(projectRoot),
|
|
10597
10633
|
...await this.checkRag(projectRoot, profile)
|
|
10598
10634
|
];
|
|
10599
10635
|
const overallStatus = deriveOverallStatus(checks);
|
|
@@ -10615,7 +10651,7 @@ var HealthChecker = class {
|
|
|
10615
10651
|
}
|
|
10616
10652
|
checkFrameworkArtifacts(projectRoot) {
|
|
10617
10653
|
const required = [PATHS.PROJECT_PROFILE, PATHS.FRAMEWORK_VERSION, PATHS.FRAMEWORK_PATH];
|
|
10618
|
-
const missing = required.filter((
|
|
10654
|
+
const missing = required.filter((relative17) => !existsSync17(join35(projectRoot, relative17)));
|
|
10619
10655
|
return missing.length === 0 ? pass("Framework artifacts exist", "Framework artifacts are present") : fail(
|
|
10620
10656
|
"Framework artifacts exist",
|
|
10621
10657
|
`Missing framework artifacts: ${missing.join(", ")}`,
|
|
@@ -10960,6 +10996,34 @@ var HealthChecker = class {
|
|
|
10960
10996
|
mcp_usage_rate: 0
|
|
10961
10997
|
};
|
|
10962
10998
|
}
|
|
10999
|
+
checkClassificationOverrideRate(projectRoot) {
|
|
11000
|
+
const path11 = join35(projectRoot, PATHS.AGENCY_CACHE_DIR, "classification-history.json");
|
|
11001
|
+
if (!existsSync17(path11)) {
|
|
11002
|
+
return pass(
|
|
11003
|
+
"Classification override rate acceptable",
|
|
11004
|
+
"No classification history recorded yet"
|
|
11005
|
+
);
|
|
11006
|
+
}
|
|
11007
|
+
try {
|
|
11008
|
+
const entries = JSON.parse(readFileSync14(path11, "utf8"));
|
|
11009
|
+
const sample = entries.slice(-50);
|
|
11010
|
+
const ratio = sample.length === 0 ? 0 : sample.filter((entry) => entry.high_override_rate).length / sample.length;
|
|
11011
|
+
return ratio > 0.3 ? warn(
|
|
11012
|
+
"Classification override rate acceptable",
|
|
11013
|
+
`High override rate detected across recent classifications (${Math.round(ratio * 100)}%)`,
|
|
11014
|
+
"Review pre-classification signals and reduce deterministic/LLM disagreement."
|
|
11015
|
+
) : pass(
|
|
11016
|
+
"Classification override rate acceptable",
|
|
11017
|
+
"Classification override rate is within acceptable bounds"
|
|
11018
|
+
);
|
|
11019
|
+
} catch {
|
|
11020
|
+
return warn(
|
|
11021
|
+
"Classification override rate acceptable",
|
|
11022
|
+
"Classification history is unreadable",
|
|
11023
|
+
"Regenerate classification history by re-running recent classification flows."
|
|
11024
|
+
);
|
|
11025
|
+
}
|
|
11026
|
+
}
|
|
10963
11027
|
documentationHasRun(projectRoot) {
|
|
10964
11028
|
return existsSync17(join35(projectRoot, PATHS.DOC_PROGRESS));
|
|
10965
11029
|
}
|
|
@@ -11163,14 +11227,14 @@ init_paths();
|
|
|
11163
11227
|
init_project_profile();
|
|
11164
11228
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
11165
11229
|
import { homedir as homedir7 } from "os";
|
|
11166
|
-
import { dirname as dirname15, join as join36 } from "path";
|
|
11230
|
+
import { dirname as dirname15, join as join36, relative as relative2, sep as sep2 } from "path";
|
|
11167
11231
|
function writeProjectProfile2(projectRoot, profile) {
|
|
11168
11232
|
return writeProjectProfile(projectRoot, profile);
|
|
11169
11233
|
}
|
|
11170
11234
|
function writeDetectionReport(projectRoot, report) {
|
|
11171
11235
|
const path11 = join36(projectRoot, PATHS.DETECTION_REPORT);
|
|
11172
11236
|
mkdirSync5(dirname15(path11), { recursive: true });
|
|
11173
|
-
writeFileSync4(path11, JSON.stringify(report, null, 2));
|
|
11237
|
+
writeFileSync4(path11, JSON.stringify(sanitizeDetectionReport(projectRoot, report), null, 2));
|
|
11174
11238
|
return path11;
|
|
11175
11239
|
}
|
|
11176
11240
|
function writeFrameworkMetadata(projectRoot, version) {
|
|
@@ -11181,18 +11245,76 @@ function writeFrameworkMetadata(projectRoot, version) {
|
|
|
11181
11245
|
updated_at=${(/* @__PURE__ */ new Date()).toISOString()}
|
|
11182
11246
|
`;
|
|
11183
11247
|
writeFileSync4(join36(projectRoot, PATHS.FRAMEWORK_VERSION), content);
|
|
11184
|
-
writeFileSync4(join36(projectRoot, PATHS.FRAMEWORK_PATH), `${
|
|
11248
|
+
writeFileSync4(join36(projectRoot, PATHS.FRAMEWORK_PATH), `${resolveFrameworkInstallReference()}
|
|
11185
11249
|
`);
|
|
11186
11250
|
}
|
|
11187
11251
|
function writeOnboardingManifest(projectRoot, manifest) {
|
|
11188
11252
|
const path11 = join36(projectRoot, PATHS.ONBOARDING_MANIFEST);
|
|
11189
11253
|
mkdirSync5(dirname15(path11), { recursive: true });
|
|
11190
|
-
writeFileSync4(path11, JSON.stringify(manifest, null, 2));
|
|
11254
|
+
writeFileSync4(path11, JSON.stringify(sanitizeOnboardingManifest(projectRoot, manifest), null, 2));
|
|
11191
11255
|
return path11;
|
|
11192
11256
|
}
|
|
11193
11257
|
function resolveFrameworkInstallPath() {
|
|
11194
11258
|
return process.env.PAQAD_FRAMEWORK_HOME ?? join36(homedir7(), ".paqad-ai/current");
|
|
11195
11259
|
}
|
|
11260
|
+
function resolveFrameworkInstallReference() {
|
|
11261
|
+
return process.env.PAQAD_FRAMEWORK_HOME ? "$PAQAD_FRAMEWORK_HOME" : "~/.paqad-ai/current";
|
|
11262
|
+
}
|
|
11263
|
+
function sanitizeDetectionReport(projectRoot, report) {
|
|
11264
|
+
return {
|
|
11265
|
+
...report,
|
|
11266
|
+
repository: report.repository ? sanitizeRepositoryContext(projectRoot, report.repository) : void 0
|
|
11267
|
+
};
|
|
11268
|
+
}
|
|
11269
|
+
function sanitizeOnboardingManifest(projectRoot, manifest) {
|
|
11270
|
+
return {
|
|
11271
|
+
...manifest,
|
|
11272
|
+
project_root: typeof manifest.project_root === "string" ? sanitizePersistedPath(projectRoot, manifest.project_root) : manifest.project_root,
|
|
11273
|
+
detected: manifest.detected ? sanitizeDetectionReport(projectRoot, manifest.detected) : null,
|
|
11274
|
+
repository: manifest.repository ? sanitizeRepositoryContext(projectRoot, manifest.repository) : void 0
|
|
11275
|
+
};
|
|
11276
|
+
}
|
|
11277
|
+
function sanitizeRepositoryContext(projectRoot, repository) {
|
|
11278
|
+
return {
|
|
11279
|
+
...repository,
|
|
11280
|
+
selected_root: sanitizePersistedPath(projectRoot, repository.selected_root),
|
|
11281
|
+
ignored_paths: repository.ignored_paths.map((path11) => sanitizePersistedPath(projectRoot, path11)),
|
|
11282
|
+
projects: repository.projects.map((project) => sanitizeRepositoryProject(projectRoot, project)),
|
|
11283
|
+
applications: repository.applications.map(
|
|
11284
|
+
(application) => sanitizeRepositoryApplication(projectRoot, application)
|
|
11285
|
+
),
|
|
11286
|
+
primary_project_root: repository.primary_project_root === null ? null : sanitizePersistedPath(projectRoot, repository.primary_project_root)
|
|
11287
|
+
};
|
|
11288
|
+
}
|
|
11289
|
+
function sanitizeRepositoryProject(projectRoot, project) {
|
|
11290
|
+
return {
|
|
11291
|
+
...project,
|
|
11292
|
+
root: sanitizePersistedPath(projectRoot, project.root),
|
|
11293
|
+
parent_root: project.parent_root === null ? null : sanitizePersistedPath(projectRoot, project.parent_root)
|
|
11294
|
+
};
|
|
11295
|
+
}
|
|
11296
|
+
function sanitizeRepositoryApplication(projectRoot, application) {
|
|
11297
|
+
return {
|
|
11298
|
+
...application,
|
|
11299
|
+
root: sanitizePersistedPath(projectRoot, application.root),
|
|
11300
|
+
component_roots: application.component_roots.map(
|
|
11301
|
+
(root) => sanitizePersistedPath(projectRoot, root)
|
|
11302
|
+
)
|
|
11303
|
+
};
|
|
11304
|
+
}
|
|
11305
|
+
function sanitizePersistedPath(projectRoot, value) {
|
|
11306
|
+
if (value === ".") {
|
|
11307
|
+
return value;
|
|
11308
|
+
}
|
|
11309
|
+
const relativePath = relative2(projectRoot, value);
|
|
11310
|
+
if (relativePath === "") {
|
|
11311
|
+
return ".";
|
|
11312
|
+
}
|
|
11313
|
+
if (relativePath !== ".." && !relativePath.startsWith(`..${sep2}`) && relativePath !== "") {
|
|
11314
|
+
return relativePath.replaceAll("\\", "/");
|
|
11315
|
+
}
|
|
11316
|
+
return value;
|
|
11317
|
+
}
|
|
11196
11318
|
|
|
11197
11319
|
// src/install/bootstrap.ts
|
|
11198
11320
|
function bootstrapFramework(projectRoot) {
|
|
@@ -11268,7 +11390,7 @@ init_esm_shims();
|
|
|
11268
11390
|
init_paths();
|
|
11269
11391
|
init_project_profile();
|
|
11270
11392
|
import { mkdir as mkdir20, readFile as readFile25, readdir as readdir6, writeFile as writeFile20 } from "fs/promises";
|
|
11271
|
-
import { dirname as dirname18, join as join41, relative as
|
|
11393
|
+
import { dirname as dirname18, join as join41, relative as relative3 } from "path";
|
|
11272
11394
|
|
|
11273
11395
|
// src/onboarding/registry-generator.ts
|
|
11274
11396
|
init_esm_shims();
|
|
@@ -12098,7 +12220,7 @@ async function gatherSourceFiles(projectRoot, stack, repository) {
|
|
|
12098
12220
|
for (const root of roots) {
|
|
12099
12221
|
try {
|
|
12100
12222
|
for (const file of await walk3(join41(projectRoot, root))) {
|
|
12101
|
-
results.add(
|
|
12223
|
+
results.add(relative3(projectRoot, file));
|
|
12102
12224
|
}
|
|
12103
12225
|
} catch {
|
|
12104
12226
|
if (!root.includes(".")) {
|
|
@@ -12685,8 +12807,8 @@ function generateFeatureDevelopmentPolicy(domain) {
|
|
|
12685
12807
|
|
|
12686
12808
|
// src/onboarding/orchestrator.ts
|
|
12687
12809
|
init_esm_shims();
|
|
12688
|
-
import { readFileSync as readFileSync16 } from "fs";
|
|
12689
|
-
import { join as
|
|
12810
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
|
|
12811
|
+
import { join as join59 } from "path";
|
|
12690
12812
|
init_paths();
|
|
12691
12813
|
init_project_intelligence();
|
|
12692
12814
|
init_runtime_paths();
|
|
@@ -12694,7 +12816,7 @@ init_runtime_paths();
|
|
|
12694
12816
|
// src/resolver/resolver.ts
|
|
12695
12817
|
init_esm_shims();
|
|
12696
12818
|
import fg6 from "fast-glob";
|
|
12697
|
-
import { basename as basename4, extname as extname2, relative as
|
|
12819
|
+
import { basename as basename4, extname as extname2, relative as relative5 } from "pathe";
|
|
12698
12820
|
|
|
12699
12821
|
// src/resolver/artifact-types.ts
|
|
12700
12822
|
init_esm_shims();
|
|
@@ -12734,7 +12856,7 @@ var ARTIFACT_OUTPUT_KEYS = {
|
|
|
12734
12856
|
|
|
12735
12857
|
// src/resolver/inheritance.ts
|
|
12736
12858
|
init_esm_shims();
|
|
12737
|
-
import { join as join44, relative as
|
|
12859
|
+
import { join as join44, relative as relative4 } from "pathe";
|
|
12738
12860
|
|
|
12739
12861
|
// src/resolver/capability-resolver.ts
|
|
12740
12862
|
init_esm_shims();
|
|
@@ -12774,7 +12896,7 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12774
12896
|
{
|
|
12775
12897
|
path: join44(runtimeRoot, "hooks"),
|
|
12776
12898
|
level: 0,
|
|
12777
|
-
source:
|
|
12899
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "hooks"))
|
|
12778
12900
|
}
|
|
12779
12901
|
];
|
|
12780
12902
|
}
|
|
@@ -12783,7 +12905,7 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12783
12905
|
{
|
|
12784
12906
|
path: join44(runtimeRoot, "templates"),
|
|
12785
12907
|
level: 0,
|
|
12786
|
-
source:
|
|
12908
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "templates"))
|
|
12787
12909
|
}
|
|
12788
12910
|
];
|
|
12789
12911
|
}
|
|
@@ -12795,12 +12917,12 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12795
12917
|
{
|
|
12796
12918
|
path: join44(runtimeRoot, "base", directoryName),
|
|
12797
12919
|
level: 0,
|
|
12798
|
-
source:
|
|
12920
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "base", directoryName))
|
|
12799
12921
|
},
|
|
12800
12922
|
{
|
|
12801
12923
|
path: join44(runtimeRoot, "capabilities", "content", directoryName),
|
|
12802
12924
|
level: 1,
|
|
12803
|
-
source:
|
|
12925
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "capabilities", "content", directoryName))
|
|
12804
12926
|
}
|
|
12805
12927
|
];
|
|
12806
12928
|
if (activeCapabilities.includes("coding")) {
|
|
@@ -12808,12 +12930,12 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12808
12930
|
{
|
|
12809
12931
|
path: join44(runtimeRoot, "capabilities", "coding", directoryName),
|
|
12810
12932
|
level: 2,
|
|
12811
|
-
source:
|
|
12933
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "capabilities", "coding", directoryName))
|
|
12812
12934
|
},
|
|
12813
12935
|
{
|
|
12814
12936
|
path: join44(runtimeRoot, "capabilities", "coding", "stacks", "_shared", directoryName),
|
|
12815
12937
|
level: 3,
|
|
12816
|
-
source:
|
|
12938
|
+
source: relative4(
|
|
12817
12939
|
runtimeRoot,
|
|
12818
12940
|
join44(runtimeRoot, "capabilities", "coding", "stacks", "_shared", directoryName)
|
|
12819
12941
|
)
|
|
@@ -12821,7 +12943,7 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12821
12943
|
...matchedPacks.map((pack, index) => ({
|
|
12822
12944
|
path: join44(runtimeRoot, "capabilities", "coding", "stacks", pack, directoryName),
|
|
12823
12945
|
level: 4 + Math.min(index, 1),
|
|
12824
|
-
source:
|
|
12946
|
+
source: relative4(
|
|
12825
12947
|
runtimeRoot,
|
|
12826
12948
|
join44(runtimeRoot, "capabilities", "coding", "stacks", pack, directoryName)
|
|
12827
12949
|
)
|
|
@@ -12830,7 +12952,7 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12830
12952
|
(pack) => resolveCapabilityDirectories(runtimeRoot, pack, traits, artifactType).map((path11) => ({
|
|
12831
12953
|
path: path11,
|
|
12832
12954
|
level: 5,
|
|
12833
|
-
source:
|
|
12955
|
+
source: relative4(runtimeRoot, path11)
|
|
12834
12956
|
}))
|
|
12835
12957
|
)
|
|
12836
12958
|
);
|
|
@@ -12839,7 +12961,7 @@ function getInheritanceDirectories(runtimeRoot, routing, artifactType) {
|
|
|
12839
12961
|
directories.push({
|
|
12840
12962
|
path: join44(runtimeRoot, "capabilities", "security", directoryName),
|
|
12841
12963
|
level: 6,
|
|
12842
|
-
source:
|
|
12964
|
+
source: relative4(runtimeRoot, join44(runtimeRoot, "capabilities", "security", directoryName))
|
|
12843
12965
|
});
|
|
12844
12966
|
}
|
|
12845
12967
|
return directories;
|
|
@@ -12961,13 +13083,13 @@ var Resolver = class {
|
|
|
12961
13083
|
const artifact = {
|
|
12962
13084
|
path: file,
|
|
12963
13085
|
level: directory.level,
|
|
12964
|
-
source:
|
|
13086
|
+
source: relative5(this.runtimeRoot, file)
|
|
12965
13087
|
};
|
|
12966
13088
|
if (COLLISION_MAP[artifactType] === "additive-merge") {
|
|
12967
13089
|
entries.push(artifact);
|
|
12968
13090
|
continue;
|
|
12969
13091
|
}
|
|
12970
|
-
overrides.set(
|
|
13092
|
+
overrides.set(relative5(directory.path, file), artifact);
|
|
12971
13093
|
}
|
|
12972
13094
|
}
|
|
12973
13095
|
const resolved = COLLISION_MAP[artifactType] === "additive-merge" ? entries : Array.from(overrides.values());
|
|
@@ -12994,13 +13116,252 @@ function getRulePriority(filePath) {
|
|
|
12994
13116
|
// src/onboarding/orchestrator.ts
|
|
12995
13117
|
init_validator();
|
|
12996
13118
|
|
|
13119
|
+
// src/planning/index.ts
|
|
13120
|
+
init_esm_shims();
|
|
13121
|
+
|
|
13122
|
+
// src/planning/contract-boundary.ts
|
|
13123
|
+
init_esm_shims();
|
|
13124
|
+
import { readFile as readFile26 } from "fs/promises";
|
|
13125
|
+
import { basename as basename5, extname as extname3, join as join45, relative as relative6 } from "path";
|
|
13126
|
+
import fg7 from "fast-glob";
|
|
13127
|
+
|
|
13128
|
+
// src/planning/cost-predictor.ts
|
|
13129
|
+
init_esm_shims();
|
|
13130
|
+
init_paths();
|
|
13131
|
+
import { mkdir as mkdir21, readFile as readFile27, writeFile as writeFile21 } from "fs/promises";
|
|
13132
|
+
import { join as join46 } from "path";
|
|
13133
|
+
|
|
13134
|
+
// src/planning/coverage-overlay.ts
|
|
13135
|
+
init_esm_shims();
|
|
13136
|
+
import { readFile as readFile28 } from "fs/promises";
|
|
13137
|
+
import { join as join47 } from "path";
|
|
13138
|
+
import fg8 from "fast-glob";
|
|
13139
|
+
|
|
13140
|
+
// src/planning/defect-advisory.ts
|
|
13141
|
+
init_esm_shims();
|
|
13142
|
+
|
|
13143
|
+
// src/planning/delta-merger.ts
|
|
13144
|
+
init_esm_shims();
|
|
13145
|
+
|
|
13146
|
+
// src/planning/doc-target-resolver.ts
|
|
13147
|
+
init_esm_shims();
|
|
13148
|
+
import { access as access2 } from "fs/promises";
|
|
13149
|
+
import { join as join48 } from "path";
|
|
13150
|
+
|
|
13151
|
+
// src/planning/intelligence-assembler.ts
|
|
13152
|
+
init_esm_shims();
|
|
13153
|
+
import { readFile as readFile31 } from "fs/promises";
|
|
13154
|
+
import { join as join51 } from "path";
|
|
13155
|
+
import fg11 from "fast-glob";
|
|
13156
|
+
|
|
13157
|
+
// src/planning/module-health.ts
|
|
13158
|
+
init_esm_shims();
|
|
13159
|
+
import { mkdir as mkdir22, readFile as readFile29, writeFile as writeFile22 } from "fs/promises";
|
|
13160
|
+
import { join as join49 } from "path";
|
|
13161
|
+
import fg9 from "fast-glob";
|
|
13162
|
+
init_paths();
|
|
13163
|
+
function deriveHealthTier(metrics) {
|
|
13164
|
+
const coverage = metrics.coverage_pct ?? null;
|
|
13165
|
+
const defectFrequency = metrics.defect_frequency ?? null;
|
|
13166
|
+
const contractStability = metrics.contract_stability ?? null;
|
|
13167
|
+
if (coverage === null && defectFrequency === null && contractStability === null) {
|
|
13168
|
+
return HEALTH_TIERS.UNKNOWN;
|
|
13169
|
+
}
|
|
13170
|
+
if (coverage !== null && coverage >= 80 && defectFrequency !== null && defectFrequency <= 2 && contractStability !== null && contractStability >= 0.85) {
|
|
13171
|
+
return HEALTH_TIERS.STABLE;
|
|
13172
|
+
}
|
|
13173
|
+
if (coverage !== null && coverage >= 50 && defectFrequency !== null && defectFrequency <= 5) {
|
|
13174
|
+
return HEALTH_TIERS.MODERATE;
|
|
13175
|
+
}
|
|
13176
|
+
return HEALTH_TIERS.FRAGILE;
|
|
13177
|
+
}
|
|
13178
|
+
async function readModuleHealth(root, moduleName) {
|
|
13179
|
+
try {
|
|
13180
|
+
const raw = await readFile29(moduleHealthPath(root, moduleName), "utf8");
|
|
13181
|
+
return JSON.parse(raw);
|
|
13182
|
+
} catch {
|
|
13183
|
+
return null;
|
|
13184
|
+
}
|
|
13185
|
+
}
|
|
13186
|
+
async function writeModuleHealth(root, moduleName, metrics) {
|
|
13187
|
+
const profile = {
|
|
13188
|
+
module: moduleName,
|
|
13189
|
+
tier: deriveHealthTier(metrics),
|
|
13190
|
+
metrics,
|
|
13191
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
13192
|
+
};
|
|
13193
|
+
await mkdir22(join49(root, PATHS.PLANNING_MODULE_HEALTH_DIR), { recursive: true });
|
|
13194
|
+
await writeFile22(
|
|
13195
|
+
moduleHealthPath(root, moduleName),
|
|
13196
|
+
JSON.stringify(profile, null, 2) + "\n",
|
|
13197
|
+
"utf8"
|
|
13198
|
+
);
|
|
13199
|
+
return profile;
|
|
13200
|
+
}
|
|
13201
|
+
async function initializeModuleHealth(root, moduleName) {
|
|
13202
|
+
const existing = await readModuleHealth(root, moduleName);
|
|
13203
|
+
if (existing) {
|
|
13204
|
+
return existing;
|
|
13205
|
+
}
|
|
13206
|
+
return writeModuleHealth(root, moduleName, {
|
|
13207
|
+
coverage_pct: null,
|
|
13208
|
+
defect_frequency: null,
|
|
13209
|
+
contract_stability: null,
|
|
13210
|
+
change_velocity: null
|
|
13211
|
+
});
|
|
13212
|
+
}
|
|
13213
|
+
function moduleHealthPath(root, moduleName) {
|
|
13214
|
+
return join49(root, PATHS.PLANNING_MODULE_HEALTH_DIR, `${moduleName}.json`);
|
|
13215
|
+
}
|
|
13216
|
+
|
|
13217
|
+
// src/planning/rule-compiler.ts
|
|
13218
|
+
init_esm_shims();
|
|
13219
|
+
init_paths();
|
|
13220
|
+
import { mkdir as mkdir23, readFile as readFile30, writeFile as writeFile23 } from "fs/promises";
|
|
13221
|
+
import { createHash as createHash9 } from "crypto";
|
|
13222
|
+
import { join as join50, relative as relative7 } from "path";
|
|
13223
|
+
import fg10 from "fast-glob";
|
|
13224
|
+
var RULE_SCHEMA_VERSION = 1;
|
|
13225
|
+
async function compileRules(root) {
|
|
13226
|
+
const files = await fg10("**/*.md", {
|
|
13227
|
+
cwd: join50(root, PATHS.RULES_DIR),
|
|
13228
|
+
onlyFiles: true
|
|
13229
|
+
});
|
|
13230
|
+
const rules = await Promise.all(
|
|
13231
|
+
files.map(async (file, index) => compileRuleFile(root, file, index + 1))
|
|
13232
|
+
);
|
|
13233
|
+
return {
|
|
13234
|
+
schema_version: RULE_SCHEMA_VERSION,
|
|
13235
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13236
|
+
source_hash: await computeSourceHash(root),
|
|
13237
|
+
rules
|
|
13238
|
+
};
|
|
13239
|
+
}
|
|
13240
|
+
async function writeCompiledRules(root, store) {
|
|
13241
|
+
const outputPath = join50(root, PATHS.COMPILED_RULES);
|
|
13242
|
+
await mkdir23(join50(root, ".paqad"), { recursive: true });
|
|
13243
|
+
await writeFile23(outputPath, JSON.stringify(store, null, 2) + "\n", "utf8");
|
|
13244
|
+
return outputPath;
|
|
13245
|
+
}
|
|
13246
|
+
async function readCompiledRules(root) {
|
|
13247
|
+
try {
|
|
13248
|
+
const raw = await readFile30(join50(root, PATHS.COMPILED_RULES), "utf8");
|
|
13249
|
+
return JSON.parse(raw);
|
|
13250
|
+
} catch {
|
|
13251
|
+
return null;
|
|
13252
|
+
}
|
|
13253
|
+
}
|
|
13254
|
+
async function isCompiledRulesStale(root) {
|
|
13255
|
+
const store = await readCompiledRules(root);
|
|
13256
|
+
if (!store) {
|
|
13257
|
+
return true;
|
|
13258
|
+
}
|
|
13259
|
+
return store.source_hash !== await computeSourceHash(root);
|
|
13260
|
+
}
|
|
13261
|
+
async function computeSourceHash(root) {
|
|
13262
|
+
const files = await fg10("**/*.md", {
|
|
13263
|
+
cwd: join50(root, PATHS.RULES_DIR),
|
|
13264
|
+
onlyFiles: true
|
|
13265
|
+
});
|
|
13266
|
+
const hash = createHash9("sha256");
|
|
13267
|
+
for (const file of files.sort()) {
|
|
13268
|
+
const content = await readFile30(join50(root, PATHS.RULES_DIR, file), "utf8");
|
|
13269
|
+
hash.update(file);
|
|
13270
|
+
hash.update("\0");
|
|
13271
|
+
hash.update(content);
|
|
13272
|
+
hash.update("\0");
|
|
13273
|
+
}
|
|
13274
|
+
return `sha256:${hash.digest("hex")}`;
|
|
13275
|
+
}
|
|
13276
|
+
async function compileRuleFile(root, file, ordinal) {
|
|
13277
|
+
const absolutePath = join50(root, PATHS.RULES_DIR, file);
|
|
13278
|
+
const raw = await readFile30(absolutePath, "utf8");
|
|
13279
|
+
const headingMatch = raw.match(/^#\s+(.+)$/m);
|
|
13280
|
+
const title = headingMatch?.[1]?.trim() || relative7(root, absolutePath);
|
|
13281
|
+
const summary = raw.split("\n").map((line) => line.trim()).find((line) => line && !line.startsWith("#") && !line.startsWith("```"));
|
|
13282
|
+
const triggerPatterns = extractTriggerPatterns(raw);
|
|
13283
|
+
if (summary === void 0) {
|
|
13284
|
+
return {
|
|
13285
|
+
rule_id: `RULE-${ordinal}`,
|
|
13286
|
+
title,
|
|
13287
|
+
source_path: join50(PATHS.RULES_DIR, file),
|
|
13288
|
+
trigger_patterns: ["**"],
|
|
13289
|
+
severity: "must",
|
|
13290
|
+
summary: "Unparseable rule content; preserve raw text for planning context.",
|
|
13291
|
+
raw_text: raw
|
|
13292
|
+
};
|
|
13293
|
+
}
|
|
13294
|
+
return {
|
|
13295
|
+
rule_id: `RULE-${ordinal}`,
|
|
13296
|
+
title,
|
|
13297
|
+
source_path: join50(PATHS.RULES_DIR, file),
|
|
13298
|
+
trigger_patterns: triggerPatterns.length > 0 ? triggerPatterns : ["**"],
|
|
13299
|
+
severity: inferSeverity(raw),
|
|
13300
|
+
summary,
|
|
13301
|
+
raw_text: raw
|
|
13302
|
+
};
|
|
13303
|
+
}
|
|
13304
|
+
function extractTriggerPatterns(raw) {
|
|
13305
|
+
const explicitDirective = raw.match(/<!--\s*trigger:\s*([^>]+)\s*-->/i)?.[1];
|
|
13306
|
+
const candidates = explicitDirective ? explicitDirective.split(",").map((value) => value.trim()) : Array.from(raw.matchAll(/`([^`]+)`/g), (match) => match[1].trim());
|
|
13307
|
+
return [...new Set(candidates.filter(Boolean))];
|
|
13308
|
+
}
|
|
13309
|
+
function inferSeverity(raw) {
|
|
13310
|
+
const normalized = raw.toLowerCase();
|
|
13311
|
+
if (/\bmust\b|\brequired\b|\bnever\b/.test(normalized)) {
|
|
13312
|
+
return "must";
|
|
13313
|
+
}
|
|
13314
|
+
if (/\bshould\b|\brecommended\b/.test(normalized)) {
|
|
13315
|
+
return "should";
|
|
13316
|
+
}
|
|
13317
|
+
return "could";
|
|
13318
|
+
}
|
|
13319
|
+
|
|
13320
|
+
// src/planning/manifest-parser.ts
|
|
13321
|
+
init_esm_shims();
|
|
13322
|
+
init_paths();
|
|
13323
|
+
import { access as access3, readFile as readFile32, readdir as readdir7 } from "fs/promises";
|
|
13324
|
+
import { createHash as createHash10 } from "crypto";
|
|
13325
|
+
import { join as join52 } from "path";
|
|
13326
|
+
import YAML9 from "yaml";
|
|
13327
|
+
|
|
13328
|
+
// src/planning/manifest-types.ts
|
|
13329
|
+
init_esm_shims();
|
|
13330
|
+
|
|
13331
|
+
// src/planning/manifest-validator.ts
|
|
13332
|
+
init_esm_shims();
|
|
13333
|
+
|
|
13334
|
+
// src/planning/plan-vs-actual.ts
|
|
13335
|
+
init_esm_shims();
|
|
13336
|
+
init_paths();
|
|
13337
|
+
import { mkdir as mkdir24, writeFile as writeFile24 } from "fs/promises";
|
|
13338
|
+
import { join as join53 } from "path";
|
|
13339
|
+
|
|
13340
|
+
// src/planning/regression-detector.ts
|
|
13341
|
+
init_esm_shims();
|
|
13342
|
+
import { readFile as readFile33 } from "fs/promises";
|
|
13343
|
+
import { basename as basename6, extname as extname4, join as join54 } from "path";
|
|
13344
|
+
import fg12 from "fast-glob";
|
|
13345
|
+
|
|
13346
|
+
// src/planning/rule-injection.ts
|
|
13347
|
+
init_esm_shims();
|
|
13348
|
+
|
|
13349
|
+
// src/planning/skeleton-emitter.ts
|
|
13350
|
+
init_esm_shims();
|
|
13351
|
+
import { mkdir as mkdir25, writeFile as writeFile25 } from "fs/promises";
|
|
13352
|
+
import { dirname as dirname20, join as join55 } from "path";
|
|
13353
|
+
|
|
13354
|
+
// src/planning/slug-utils.ts
|
|
13355
|
+
init_esm_shims();
|
|
13356
|
+
|
|
12997
13357
|
// src/onboarding/gitignore-writer.ts
|
|
12998
13358
|
init_esm_shims();
|
|
12999
13359
|
import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
|
|
13000
|
-
import { join as
|
|
13360
|
+
import { join as join56 } from "path";
|
|
13001
13361
|
var PAQAD_MARKER = "# paqad-ai";
|
|
13002
13362
|
var PAQAD_GITIGNORE_ENTRIES = [
|
|
13003
13363
|
PAQAD_MARKER,
|
|
13364
|
+
".paqad/framework-path.txt",
|
|
13004
13365
|
".paqad/cache/",
|
|
13005
13366
|
".paqad/session/",
|
|
13006
13367
|
".paqad/context/",
|
|
@@ -13012,7 +13373,7 @@ var PAQAD_GITIGNORE_ENTRIES = [
|
|
|
13012
13373
|
".paqad/theme/"
|
|
13013
13374
|
].join("\n");
|
|
13014
13375
|
function writeGitignore(projectRoot) {
|
|
13015
|
-
const gitignorePath =
|
|
13376
|
+
const gitignorePath = join56(projectRoot, ".gitignore");
|
|
13016
13377
|
const existing = existsSync20(gitignorePath) ? readFileSync15(gitignorePath, "utf8") : "";
|
|
13017
13378
|
if (existing.includes(PAQAD_MARKER)) {
|
|
13018
13379
|
return;
|
|
@@ -13706,9 +14067,9 @@ async function enableRagDuringOnboarding(projectRoot, ragSelection) {
|
|
|
13706
14067
|
init_esm_shims();
|
|
13707
14068
|
init_paths();
|
|
13708
14069
|
import { existsSync as existsSync21 } from "fs";
|
|
13709
|
-
import { readFile as
|
|
13710
|
-
import { join as
|
|
13711
|
-
import
|
|
14070
|
+
import { readFile as readFile34 } from "fs/promises";
|
|
14071
|
+
import { join as join57, relative as relative8 } from "path";
|
|
14072
|
+
import fg13 from "fast-glob";
|
|
13712
14073
|
async function generateReferenceGuides(runtimeRoot, context) {
|
|
13713
14074
|
if (context.domain !== "coding") {
|
|
13714
14075
|
return [];
|
|
@@ -13718,11 +14079,11 @@ async function generateReferenceGuides(runtimeRoot, context) {
|
|
|
13718
14079
|
routing: { domain: context.domain },
|
|
13719
14080
|
stack_profile: context.stack_profile
|
|
13720
14081
|
});
|
|
13721
|
-
const referencesRoot =
|
|
14082
|
+
const referencesRoot = join57(runtimeRoot, "capabilities", "coding", "stacks", stack, "references");
|
|
13722
14083
|
if (!existsSync21(referencesRoot)) {
|
|
13723
14084
|
return [buildFallbackReferenceGuide(stack)];
|
|
13724
14085
|
}
|
|
13725
|
-
const entries = await
|
|
14086
|
+
const entries = await fg13(["tools/*.md", "tools-catalog.md"], {
|
|
13726
14087
|
cwd: referencesRoot,
|
|
13727
14088
|
onlyFiles: true,
|
|
13728
14089
|
absolute: true
|
|
@@ -13732,8 +14093,8 @@ async function generateReferenceGuides(runtimeRoot, context) {
|
|
|
13732
14093
|
}
|
|
13733
14094
|
return Promise.all(
|
|
13734
14095
|
entries.sort().map(async (entry) => ({
|
|
13735
|
-
path: toProjectReferencePath(stack,
|
|
13736
|
-
content: await
|
|
14096
|
+
path: toProjectReferencePath(stack, relative8(referencesRoot, entry)),
|
|
14097
|
+
content: await readFile34(entry, "utf8"),
|
|
13737
14098
|
autoUpdate: false
|
|
13738
14099
|
}))
|
|
13739
14100
|
);
|
|
@@ -13741,14 +14102,14 @@ async function generateReferenceGuides(runtimeRoot, context) {
|
|
|
13741
14102
|
function toProjectReferencePath(stack, relativePath) {
|
|
13742
14103
|
const normalized = relativePath.replaceAll("\\", "/");
|
|
13743
14104
|
if (normalized === "tools-catalog.md") {
|
|
13744
|
-
return
|
|
14105
|
+
return join57(PATHS.TOOLS_DIR, stack, "README.md");
|
|
13745
14106
|
}
|
|
13746
|
-
return
|
|
14107
|
+
return join57(PATHS.TOOLS_DIR, stack, normalized.replace(/^tools\//, ""));
|
|
13747
14108
|
}
|
|
13748
14109
|
function buildFallbackReferenceGuide(stack) {
|
|
13749
14110
|
const title = stack.split("-").map((segment) => segment.slice(0, 1).toUpperCase() + segment.slice(1)).join(" ");
|
|
13750
14111
|
return {
|
|
13751
|
-
path:
|
|
14112
|
+
path: join57(PATHS.TOOLS_DIR, stack, "README.md"),
|
|
13752
14113
|
autoUpdate: false,
|
|
13753
14114
|
content: [
|
|
13754
14115
|
`# ${title} Tool References`,
|
|
@@ -13767,13 +14128,13 @@ function buildFallbackReferenceGuide(stack) {
|
|
|
13767
14128
|
// src/onboarding/rule-generator.ts
|
|
13768
14129
|
init_esm_shims();
|
|
13769
14130
|
init_paths();
|
|
13770
|
-
import { readFile as
|
|
13771
|
-
import { join as
|
|
14131
|
+
import { readFile as readFile35 } from "fs/promises";
|
|
14132
|
+
import { join as join58 } from "path";
|
|
13772
14133
|
async function generateProjectRules(rules) {
|
|
13773
14134
|
return Promise.all(
|
|
13774
14135
|
rules.map(async (rule) => ({
|
|
13775
14136
|
path: toProjectRulePath(rule.source),
|
|
13776
|
-
content: await
|
|
14137
|
+
content: await readFile35(rule.path, "utf8"),
|
|
13777
14138
|
autoUpdate: false
|
|
13778
14139
|
}))
|
|
13779
14140
|
);
|
|
@@ -13781,22 +14142,22 @@ async function generateProjectRules(rules) {
|
|
|
13781
14142
|
function toProjectRulePath(source) {
|
|
13782
14143
|
const normalized = source.replaceAll("\\", "/");
|
|
13783
14144
|
if (normalized.startsWith("base/rules/")) {
|
|
13784
|
-
return
|
|
14145
|
+
return join58(PATHS.RULES_DIR, "_shared", normalized.replace(/^base\/rules\//, ""));
|
|
13785
14146
|
}
|
|
13786
14147
|
if (normalized.startsWith("capabilities/")) {
|
|
13787
14148
|
const capabilityNormalized = normalized.replace(/^capabilities\//, "");
|
|
13788
14149
|
const [prefix2, suffix2] = capabilityNormalized.split("/rules/");
|
|
13789
14150
|
if (prefix2 !== void 0 && suffix2 !== void 0) {
|
|
13790
14151
|
const target2 = suffix2.endsWith("/guide.md") ? suffix2.replace("/guide.md", ".md") : suffix2;
|
|
13791
|
-
return
|
|
14152
|
+
return join58(PATHS.RULES_DIR, prefix2, target2);
|
|
13792
14153
|
}
|
|
13793
14154
|
}
|
|
13794
14155
|
const [prefix, suffix] = normalized.split("/rules/");
|
|
13795
14156
|
if (prefix === void 0 || suffix === void 0) {
|
|
13796
|
-
return
|
|
14157
|
+
return join58(PATHS.RULES_DIR, normalized);
|
|
13797
14158
|
}
|
|
13798
14159
|
const target = suffix.endsWith("/guide.md") ? suffix.replace("/guide.md", ".md") : suffix;
|
|
13799
|
-
return
|
|
14160
|
+
return join58(PATHS.RULES_DIR, prefix, target);
|
|
13800
14161
|
}
|
|
13801
14162
|
|
|
13802
14163
|
// src/onboarding/orchestrator.ts
|
|
@@ -13852,7 +14213,7 @@ var OnboardingOrchestrator = class {
|
|
|
13852
14213
|
stack_profile: selections.stack_profile
|
|
13853
14214
|
})
|
|
13854
14215
|
);
|
|
13855
|
-
const silentUpdateSrc =
|
|
14216
|
+
const silentUpdateSrc = join59(runtimeRoot, "hooks", "silent-update.sh");
|
|
13856
14217
|
try {
|
|
13857
14218
|
const hookContent = readFileSync16(silentUpdateSrc, "utf8");
|
|
13858
14219
|
generatedFiles.push({
|
|
@@ -13887,6 +14248,81 @@ var OnboardingOrchestrator = class {
|
|
|
13887
14248
|
writeDetectionReport(options.projectRoot, detection);
|
|
13888
14249
|
writeFrameworkMetadata(options.projectRoot, VERSION);
|
|
13889
14250
|
bootstrapFramework(options.projectRoot);
|
|
14251
|
+
let compiledRulesPath = join59(options.projectRoot, PATHS.COMPILED_RULES);
|
|
14252
|
+
let initializedModules = [];
|
|
14253
|
+
try {
|
|
14254
|
+
if (await isCompiledRulesStale(options.projectRoot)) {
|
|
14255
|
+
const compiledRules = await compileRules(options.projectRoot);
|
|
14256
|
+
compiledRulesPath = await writeCompiledRules(options.projectRoot, compiledRules);
|
|
14257
|
+
}
|
|
14258
|
+
} catch (error) {
|
|
14259
|
+
onboardingWarnings.push(
|
|
14260
|
+
`Planning rule compilation failed during onboarding: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
14261
|
+
);
|
|
14262
|
+
}
|
|
14263
|
+
try {
|
|
14264
|
+
initializedModules = await Promise.all(
|
|
14265
|
+
modules.map(async (moduleName) => {
|
|
14266
|
+
await initializeModuleHealth(options.projectRoot, moduleName);
|
|
14267
|
+
return moduleName;
|
|
14268
|
+
})
|
|
14269
|
+
);
|
|
14270
|
+
} catch (error) {
|
|
14271
|
+
onboardingWarnings.push(
|
|
14272
|
+
`Planning module health initialization failed during onboarding: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
14273
|
+
);
|
|
14274
|
+
}
|
|
14275
|
+
try {
|
|
14276
|
+
await ensureStoreDir(join59(options.projectRoot, ".paqad", "defect-patterns"));
|
|
14277
|
+
} catch (error) {
|
|
14278
|
+
onboardingWarnings.push(
|
|
14279
|
+
`Defect pattern store initialization failed during onboarding: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
14280
|
+
);
|
|
14281
|
+
}
|
|
14282
|
+
try {
|
|
14283
|
+
const classifierConfigPath = join59(options.projectRoot, ".paqad", "classifier-config.json");
|
|
14284
|
+
writeFileSync7(
|
|
14285
|
+
classifierConfigPath,
|
|
14286
|
+
JSON.stringify(
|
|
14287
|
+
{
|
|
14288
|
+
schema_version: 1,
|
|
14289
|
+
workflow_patterns: [
|
|
14290
|
+
{
|
|
14291
|
+
workflow: "pentest-retest",
|
|
14292
|
+
priority: 250,
|
|
14293
|
+
patterns: ["pentest retest", "pentest-retest"]
|
|
14294
|
+
},
|
|
14295
|
+
{
|
|
14296
|
+
workflow: "pentest",
|
|
14297
|
+
priority: 240,
|
|
14298
|
+
patterns: ["run a pentest", "penetration test", "security audit"]
|
|
14299
|
+
},
|
|
14300
|
+
{ workflow: "root-cause-analysis", priority: 230, patterns: ["root cause", "rca"] },
|
|
14301
|
+
{
|
|
14302
|
+
workflow: "documentation-update",
|
|
14303
|
+
priority: 200,
|
|
14304
|
+
patterns: ["documentation", "docs", "documenation"]
|
|
14305
|
+
},
|
|
14306
|
+
{ workflow: "research", priority: 180, patterns: ["research", "investigate"] },
|
|
14307
|
+
{ workflow: "cleanup", priority: 170, patterns: ["cleanup", "clean up"] },
|
|
14308
|
+
{ workflow: "bug-fix", priority: 160, patterns: ["fix", "bug"] },
|
|
14309
|
+
{
|
|
14310
|
+
workflow: "feature-development",
|
|
14311
|
+
priority: 140,
|
|
14312
|
+
patterns: ["implement", "build", "add", "feature", "develop"]
|
|
14313
|
+
}
|
|
14314
|
+
]
|
|
14315
|
+
},
|
|
14316
|
+
null,
|
|
14317
|
+
2
|
|
14318
|
+
) + "\n"
|
|
14319
|
+
);
|
|
14320
|
+
writeResult.written.push(".paqad/classifier-config.json");
|
|
14321
|
+
} catch (error) {
|
|
14322
|
+
onboardingWarnings.push(
|
|
14323
|
+
`Classifier config initialization failed during onboarding: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
14324
|
+
);
|
|
14325
|
+
}
|
|
13890
14326
|
const manifestPath = writeOnboardingManifest(options.projectRoot, {
|
|
13891
14327
|
framework_version: VERSION,
|
|
13892
14328
|
adapter: adapters[0],
|
|
@@ -13899,7 +14335,12 @@ var OnboardingOrchestrator = class {
|
|
|
13899
14335
|
path: file.path,
|
|
13900
14336
|
auto_update: file.autoUpdate,
|
|
13901
14337
|
executable: file.executable
|
|
13902
|
-
}))
|
|
14338
|
+
})),
|
|
14339
|
+
planning_artifacts: {
|
|
14340
|
+
compiled_rules_path: compiledRulesPath,
|
|
14341
|
+
module_health_initialized: initializedModules,
|
|
14342
|
+
classifier_config_path: ".paqad/classifier-config.json"
|
|
14343
|
+
}
|
|
13903
14344
|
});
|
|
13904
14345
|
return {
|
|
13905
14346
|
adapter: adapters[0],
|
|
@@ -14164,7 +14605,7 @@ function buildRustCommands(usingCompose) {
|
|
|
14164
14605
|
init_esm_shims();
|
|
14165
14606
|
init_paths();
|
|
14166
14607
|
init_runtime_paths();
|
|
14167
|
-
import { join as
|
|
14608
|
+
import { join as join60 } from "path";
|
|
14168
14609
|
|
|
14169
14610
|
// src/templates/index.ts
|
|
14170
14611
|
init_esm_shims();
|
|
@@ -14195,13 +14636,13 @@ init_esm_shims();
|
|
|
14195
14636
|
|
|
14196
14637
|
// src/templates/registry.ts
|
|
14197
14638
|
init_esm_shims();
|
|
14198
|
-
import
|
|
14199
|
-
import { basename as
|
|
14639
|
+
import fg14 from "fast-glob";
|
|
14640
|
+
import { basename as basename7, relative as relative9 } from "pathe";
|
|
14200
14641
|
|
|
14201
14642
|
// src/onboarding/scaffold-generator.ts
|
|
14202
14643
|
var FEATURE_TEMPLATE_TARGETS = [
|
|
14203
|
-
["business.md.hbs",
|
|
14204
|
-
["technical.md.hbs",
|
|
14644
|
+
["business.md.hbs", join60(PATHS.MODULE_FEATURES_DIR, "core", "business.md")],
|
|
14645
|
+
["technical.md.hbs", join60(PATHS.MODULE_FEATURES_DIR, "core", "technical.md")]
|
|
14205
14646
|
];
|
|
14206
14647
|
|
|
14207
14648
|
// src/packs/index.ts
|
|
@@ -14275,19 +14716,19 @@ async function queryOsv(packages) {
|
|
|
14275
14716
|
init_esm_shims();
|
|
14276
14717
|
init_paths();
|
|
14277
14718
|
import { existsSync as existsSync23 } from "fs";
|
|
14278
|
-
import { mkdir as
|
|
14279
|
-
import { dirname as
|
|
14719
|
+
import { mkdir as mkdir27, readdir as readdir9, readFile as readFile37, writeFile as writeFile27 } from "fs/promises";
|
|
14720
|
+
import { dirname as dirname22, join as join62 } from "path";
|
|
14280
14721
|
init_validator();
|
|
14281
14722
|
|
|
14282
14723
|
// src/pentest/shared.ts
|
|
14283
14724
|
init_esm_shims();
|
|
14284
14725
|
init_paths();
|
|
14285
|
-
import { createHash as
|
|
14726
|
+
import { createHash as createHash11 } from "crypto";
|
|
14286
14727
|
import { existsSync as existsSync22 } from "fs";
|
|
14287
|
-
import { mkdir as
|
|
14288
|
-
import { basename as
|
|
14728
|
+
import { mkdir as mkdir26, readFile as readFile36, readdir as readdir8, writeFile as writeFile26 } from "fs/promises";
|
|
14729
|
+
import { basename as basename8, dirname as dirname21, join as join61, relative as relative10 } from "path";
|
|
14289
14730
|
import { execa as execa2 } from "execa";
|
|
14290
|
-
import
|
|
14731
|
+
import fg15 from "fast-glob";
|
|
14291
14732
|
function toLocalTimestamp(date) {
|
|
14292
14733
|
const year = date.getFullYear();
|
|
14293
14734
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -14298,18 +14739,18 @@ function toLocalTimestamp(date) {
|
|
|
14298
14739
|
return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}`;
|
|
14299
14740
|
}
|
|
14300
14741
|
async function writeJson(target, data) {
|
|
14301
|
-
await
|
|
14302
|
-
await
|
|
14742
|
+
await mkdir26(dirname21(target), { recursive: true });
|
|
14743
|
+
await writeFile26(target, `${JSON.stringify(data, null, 2)}
|
|
14303
14744
|
`);
|
|
14304
14745
|
}
|
|
14305
14746
|
async function readJsonIfExists(target) {
|
|
14306
14747
|
if (!existsSync22(target)) {
|
|
14307
14748
|
return null;
|
|
14308
14749
|
}
|
|
14309
|
-
return JSON.parse(await
|
|
14750
|
+
return JSON.parse(await readFile36(target, "utf8"));
|
|
14310
14751
|
}
|
|
14311
14752
|
async function hashRelevantInputs(projectRoot, workflow, extra = {}) {
|
|
14312
|
-
const files = (await
|
|
14753
|
+
const files = (await fg15(
|
|
14313
14754
|
[
|
|
14314
14755
|
"docs/modules/**/*.md",
|
|
14315
14756
|
"tests/**/*",
|
|
@@ -14334,11 +14775,11 @@ async function hashRelevantInputs(projectRoot, workflow, extra = {}) {
|
|
|
14334
14775
|
dot: true
|
|
14335
14776
|
}
|
|
14336
14777
|
)).sort();
|
|
14337
|
-
const hash =
|
|
14778
|
+
const hash = createHash11("sha256");
|
|
14338
14779
|
hash.update(workflow);
|
|
14339
14780
|
for (const file of files) {
|
|
14340
|
-
hash.update(
|
|
14341
|
-
hash.update(await
|
|
14781
|
+
hash.update(relative10(projectRoot, file));
|
|
14782
|
+
hash.update(await readFile36(file));
|
|
14342
14783
|
}
|
|
14343
14784
|
hash.update(JSON.stringify(extra));
|
|
14344
14785
|
return hash.digest("hex");
|
|
@@ -14349,11 +14790,11 @@ async function discoverTargetUrl(projectRoot, stack, explicit) {
|
|
|
14349
14790
|
}
|
|
14350
14791
|
const envFiles = [".env", ".env.local", ".env.example"];
|
|
14351
14792
|
for (const envFile of envFiles) {
|
|
14352
|
-
const path11 =
|
|
14793
|
+
const path11 = join61(projectRoot, envFile);
|
|
14353
14794
|
if (!existsSync22(path11)) {
|
|
14354
14795
|
continue;
|
|
14355
14796
|
}
|
|
14356
|
-
const content = await
|
|
14797
|
+
const content = await readFile36(path11, "utf8");
|
|
14357
14798
|
const match = content.match(/(?:^|\n)\s*APP_URL\s*=\s*["']?([^\n"']+)["']?/i) ?? content.match(/(?:^|\n)\s*VITE_APP_URL\s*=\s*["']?([^\n"']+)["']?/i) ?? content.match(/(?:^|\n)\s*VITE_BASE_URL\s*=\s*["']?([^\n"']+)["']?/i);
|
|
14358
14799
|
if (match?.[1]) {
|
|
14359
14800
|
return match[1].trim();
|
|
@@ -14371,18 +14812,18 @@ async function discoverTargetUrl(projectRoot, stack, explicit) {
|
|
|
14371
14812
|
return null;
|
|
14372
14813
|
}
|
|
14373
14814
|
async function runProjectScript(projectRoot, scriptName, env, logDir) {
|
|
14374
|
-
const scriptPath =
|
|
14375
|
-
const stdoutPath =
|
|
14376
|
-
const stderrPath =
|
|
14377
|
-
await
|
|
14815
|
+
const scriptPath = join61(projectRoot, PATHS.SCRIPTS_DIR, scriptName);
|
|
14816
|
+
const stdoutPath = join61(logDir, `${scriptName}.stdout.log`);
|
|
14817
|
+
const stderrPath = join61(logDir, `${scriptName}.stderr.log`);
|
|
14818
|
+
await mkdir26(logDir, { recursive: true });
|
|
14378
14819
|
if (!existsSync22(scriptPath)) {
|
|
14379
|
-
await
|
|
14380
|
-
await
|
|
14820
|
+
await writeFile26(stdoutPath, "");
|
|
14821
|
+
await writeFile26(stderrPath, `Missing script: ${relative10(projectRoot, scriptPath)}
|
|
14381
14822
|
`);
|
|
14382
14823
|
return {
|
|
14383
14824
|
script: scriptName,
|
|
14384
14825
|
status: "blocked",
|
|
14385
|
-
artifact_paths: [
|
|
14826
|
+
artifact_paths: [relative10(projectRoot, stdoutPath), relative10(projectRoot, stderrPath)],
|
|
14386
14827
|
exit_code: null,
|
|
14387
14828
|
summary: `Missing project script ${scriptName}`
|
|
14388
14829
|
};
|
|
@@ -14392,25 +14833,25 @@ async function runProjectScript(projectRoot, scriptName, env, logDir) {
|
|
|
14392
14833
|
env,
|
|
14393
14834
|
reject: false
|
|
14394
14835
|
});
|
|
14395
|
-
await
|
|
14396
|
-
await
|
|
14836
|
+
await writeFile26(stdoutPath, result.stdout);
|
|
14837
|
+
await writeFile26(stderrPath, result.stderr);
|
|
14397
14838
|
return {
|
|
14398
14839
|
script: scriptName,
|
|
14399
14840
|
status: result.exitCode === 0 ? "completed" : "failed",
|
|
14400
|
-
artifact_paths: [
|
|
14841
|
+
artifact_paths: [relative10(projectRoot, stdoutPath), relative10(projectRoot, stderrPath)],
|
|
14401
14842
|
exit_code: result.exitCode ?? null,
|
|
14402
14843
|
summary: result.exitCode === 0 ? `${scriptName} completed` : `${scriptName} failed with exit code ${result.exitCode}`
|
|
14403
14844
|
};
|
|
14404
14845
|
}
|
|
14405
14846
|
async function loadModuleDocs(projectRoot, focusModules = []) {
|
|
14406
|
-
const moduleRoot =
|
|
14847
|
+
const moduleRoot = join61(projectRoot, PATHS.MODULES_DIR);
|
|
14407
14848
|
if (!existsSync22(moduleRoot)) {
|
|
14408
14849
|
return [];
|
|
14409
14850
|
}
|
|
14410
|
-
const dirs = (await
|
|
14851
|
+
const dirs = (await readdir8(moduleRoot, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((moduleName) => focusModules.length === 0 || focusModules.includes(moduleName)).sort();
|
|
14411
14852
|
return Promise.all(
|
|
14412
14853
|
dirs.map(async (moduleName) => {
|
|
14413
|
-
const paths = (await
|
|
14854
|
+
const paths = (await fg15(
|
|
14414
14855
|
[
|
|
14415
14856
|
`${moduleName}/business.md`,
|
|
14416
14857
|
`${moduleName}/technical.md`,
|
|
@@ -14428,17 +14869,17 @@ async function loadModuleDocs(projectRoot, focusModules = []) {
|
|
|
14428
14869
|
absolute: true
|
|
14429
14870
|
}
|
|
14430
14871
|
)).sort();
|
|
14431
|
-
const content = (await Promise.all(paths.map((path11) =>
|
|
14872
|
+
const content = (await Promise.all(paths.map((path11) => readFile36(path11, "utf8").catch(() => "")))).join("\n");
|
|
14432
14873
|
return {
|
|
14433
14874
|
module: moduleName,
|
|
14434
|
-
paths: paths.map((path11) =>
|
|
14875
|
+
paths: paths.map((path11) => relative10(projectRoot, path11)),
|
|
14435
14876
|
content
|
|
14436
14877
|
};
|
|
14437
14878
|
})
|
|
14438
14879
|
);
|
|
14439
14880
|
}
|
|
14440
14881
|
async function loadTests(projectRoot, focusModules = []) {
|
|
14441
|
-
const files = (await
|
|
14882
|
+
const files = (await fg15(["tests/**/*.{ts,tsx,js,jsx,php,dart}", "src/**/*.{test,spec}.{ts,tsx,js,jsx}"], {
|
|
14442
14883
|
cwd: projectRoot,
|
|
14443
14884
|
onlyFiles: true,
|
|
14444
14885
|
absolute: true
|
|
@@ -14449,8 +14890,8 @@ async function loadTests(projectRoot, focusModules = []) {
|
|
|
14449
14890
|
) : files;
|
|
14450
14891
|
return Promise.all(
|
|
14451
14892
|
filtered.map(async (path11) => ({
|
|
14452
|
-
path:
|
|
14453
|
-
content: await
|
|
14893
|
+
path: relative10(projectRoot, path11),
|
|
14894
|
+
content: await readFile36(path11, "utf8").catch(() => "")
|
|
14454
14895
|
}))
|
|
14455
14896
|
);
|
|
14456
14897
|
}
|
|
@@ -14472,7 +14913,7 @@ function inferSourceArtifacts(baseDir, scriptResults) {
|
|
|
14472
14913
|
return [
|
|
14473
14914
|
...new Set(
|
|
14474
14915
|
artifacts.map(
|
|
14475
|
-
(artifact) => artifact.startsWith(".") ? artifact :
|
|
14916
|
+
(artifact) => artifact.startsWith(".") ? artifact : relative10(dirname21(baseDir), join61(dirname21(baseDir), artifact))
|
|
14476
14917
|
)
|
|
14477
14918
|
)
|
|
14478
14919
|
];
|
|
@@ -14546,11 +14987,11 @@ var PentestProgressTracker = class {
|
|
|
14546
14987
|
};
|
|
14547
14988
|
}
|
|
14548
14989
|
async load(projectRoot, runId) {
|
|
14549
|
-
const target =
|
|
14990
|
+
const target = join62(projectRoot, PATHS.PENTEST_RUNS_DIR, runId, "progress.json");
|
|
14550
14991
|
if (!existsSync23(target)) {
|
|
14551
14992
|
return null;
|
|
14552
14993
|
}
|
|
14553
|
-
const parsed = JSON.parse(await
|
|
14994
|
+
const parsed = JSON.parse(await readFile37(target, "utf8"));
|
|
14554
14995
|
const validation = this.validator.validate("pentest-progress", parsed);
|
|
14555
14996
|
if (!validation.valid) {
|
|
14556
14997
|
throw new Error(validation.errors.map((error) => error.message).join("; "));
|
|
@@ -14558,10 +14999,10 @@ var PentestProgressTracker = class {
|
|
|
14558
14999
|
return parsed;
|
|
14559
15000
|
}
|
|
14560
15001
|
async save(projectRoot, progress) {
|
|
14561
|
-
const target =
|
|
15002
|
+
const target = join62(projectRoot, PATHS.PENTEST_RUNS_DIR, progress.run_id, "progress.json");
|
|
14562
15003
|
progress.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
14563
|
-
await
|
|
14564
|
-
await
|
|
15004
|
+
await mkdir27(dirname22(target), { recursive: true });
|
|
15005
|
+
await writeFile27(target, `${JSON.stringify(progress, null, 2)}
|
|
14565
15006
|
`);
|
|
14566
15007
|
}
|
|
14567
15008
|
markStepRunning(progress, stepId, inputHash) {
|
|
@@ -14617,11 +15058,11 @@ var PentestProgressTracker = class {
|
|
|
14617
15058
|
return step.status === "completed" && step.input_hash === inputHash;
|
|
14618
15059
|
}
|
|
14619
15060
|
async findIncompleteRun(projectRoot, workflow, sourceReportPath) {
|
|
14620
|
-
const runsDir =
|
|
15061
|
+
const runsDir = join62(projectRoot, PATHS.PENTEST_RUNS_DIR);
|
|
14621
15062
|
if (!existsSync23(runsDir)) {
|
|
14622
15063
|
return null;
|
|
14623
15064
|
}
|
|
14624
|
-
const entries = (await
|
|
15065
|
+
const entries = (await readdir9(runsDir, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().reverse();
|
|
14625
15066
|
for (const runId of entries) {
|
|
14626
15067
|
const progress = await this.load(projectRoot, runId);
|
|
14627
15068
|
if (progress === null) {
|
|
@@ -14660,10 +15101,10 @@ var PentestProgressTracker = class {
|
|
|
14660
15101
|
}
|
|
14661
15102
|
};
|
|
14662
15103
|
function runArtifactsDir(projectRoot, runId) {
|
|
14663
|
-
return
|
|
15104
|
+
return join62(projectRoot, PATHS.PENTEST_RUNS_DIR, runId, "artifacts");
|
|
14664
15105
|
}
|
|
14665
15106
|
function runLogsDir(projectRoot, runId) {
|
|
14666
|
-
return
|
|
15107
|
+
return join62(projectRoot, PATHS.PENTEST_RUNS_DIR, runId, "logs");
|
|
14667
15108
|
}
|
|
14668
15109
|
|
|
14669
15110
|
// src/pipeline/index.ts
|
|
@@ -14672,21 +15113,61 @@ init_esm_shims();
|
|
|
14672
15113
|
// src/pipeline/classifier.ts
|
|
14673
15114
|
init_esm_shims();
|
|
14674
15115
|
|
|
15116
|
+
// src/pipeline/confidence-scorer.ts
|
|
15117
|
+
init_esm_shims();
|
|
15118
|
+
|
|
15119
|
+
// src/pipeline/post-classifier.ts
|
|
15120
|
+
init_esm_shims();
|
|
15121
|
+
import { mkdir as mkdir28, readFile as readFile38, readdir as readdir10, writeFile as writeFile28 } from "fs/promises";
|
|
15122
|
+
import { join as join63 } from "path";
|
|
15123
|
+
init_paths();
|
|
15124
|
+
|
|
15125
|
+
// src/pipeline/pre-classifier.ts
|
|
15126
|
+
init_esm_shims();
|
|
15127
|
+
|
|
15128
|
+
// src/pipeline/context-budget-estimator.ts
|
|
15129
|
+
init_esm_shims();
|
|
15130
|
+
|
|
15131
|
+
// src/pipeline/delta-detector.ts
|
|
15132
|
+
init_esm_shims();
|
|
15133
|
+
|
|
15134
|
+
// src/pipeline/impact-resolver.ts
|
|
15135
|
+
init_esm_shims();
|
|
15136
|
+
|
|
15137
|
+
// src/pipeline/module-resolver.ts
|
|
15138
|
+
init_esm_shims();
|
|
15139
|
+
init_chunk_index();
|
|
15140
|
+
init_service();
|
|
15141
|
+
import { existsSync as existsSync24 } from "fs";
|
|
15142
|
+
import { readdir as readdir11 } from "fs/promises";
|
|
15143
|
+
import { basename as basename9, join as join64, relative as relative11 } from "path";
|
|
15144
|
+
|
|
15145
|
+
// src/pipeline/rule-trigger-matcher.ts
|
|
15146
|
+
init_esm_shims();
|
|
15147
|
+
|
|
15148
|
+
// src/pipeline/scope-resolver.ts
|
|
15149
|
+
init_esm_shims();
|
|
15150
|
+
import { readFile as readFile39 } from "fs/promises";
|
|
15151
|
+
import { join as join65, relative as relative12 } from "path";
|
|
15152
|
+
|
|
15153
|
+
// src/pipeline/llm-skip-evaluator.ts
|
|
15154
|
+
init_esm_shims();
|
|
15155
|
+
|
|
14675
15156
|
// src/pipeline/lane-runner.ts
|
|
14676
15157
|
init_esm_shims();
|
|
14677
15158
|
init_paths();
|
|
14678
15159
|
init_runtime_paths();
|
|
14679
|
-
import { existsSync as
|
|
14680
|
-
import { mkdir as
|
|
14681
|
-
import { dirname as
|
|
14682
|
-
import { basename as
|
|
14683
|
-
import
|
|
15160
|
+
import { existsSync as existsSync28 } from "fs";
|
|
15161
|
+
import { mkdir as mkdir34, readFile as readFile47, rename as rename3, writeFile as writeFile34 } from "fs/promises";
|
|
15162
|
+
import { dirname as dirname27, join as join77 } from "path";
|
|
15163
|
+
import { basename as basename10, dirname as pathDirname } from "pathe";
|
|
15164
|
+
import fg18 from "fast-glob";
|
|
14684
15165
|
init_project_profile();
|
|
14685
15166
|
|
|
14686
15167
|
// src/workflows/engine.ts
|
|
14687
15168
|
init_esm_shims();
|
|
14688
|
-
import { readFile as
|
|
14689
|
-
import { join as
|
|
15169
|
+
import { readFile as readFile40, writeFile as writeFile29, mkdir as mkdir29 } from "fs/promises";
|
|
15170
|
+
import { join as join66, dirname as dirname23 } from "path";
|
|
14690
15171
|
import { randomUUID } from "crypto";
|
|
14691
15172
|
|
|
14692
15173
|
// src/workflows/template-validator.ts
|
|
@@ -14727,7 +15208,30 @@ function createFailResult(phase, summary, context) {
|
|
|
14727
15208
|
var ClassifyPhase = class {
|
|
14728
15209
|
phase = "request-classification";
|
|
14729
15210
|
async execute(context) {
|
|
14730
|
-
|
|
15211
|
+
const confidence = context.classification.classification_confidence;
|
|
15212
|
+
const resolutionMap = context.classification.resolution_map;
|
|
15213
|
+
if (confidence === void 0) {
|
|
15214
|
+
return createPassResult(
|
|
15215
|
+
this.phase,
|
|
15216
|
+
"Classification confirmed (legacy result without confidence metadata)",
|
|
15217
|
+
context
|
|
15218
|
+
);
|
|
15219
|
+
}
|
|
15220
|
+
if (confidence < 0.5) {
|
|
15221
|
+
return createPassResult(
|
|
15222
|
+
this.phase,
|
|
15223
|
+
"Classification confidence below 0.5; treat downstream planning as tentative",
|
|
15224
|
+
context
|
|
15225
|
+
);
|
|
15226
|
+
}
|
|
15227
|
+
const guessedCount = Object.values(resolutionMap ?? {}).filter(
|
|
15228
|
+
(source) => source === "llm-guessed"
|
|
15229
|
+
).length;
|
|
15230
|
+
return createPassResult(
|
|
15231
|
+
this.phase,
|
|
15232
|
+
guessedCount > 0 ? `Classification confirmed with ${guessedCount} tentative dimension(s)` : "Classification confirmed",
|
|
15233
|
+
context
|
|
15234
|
+
);
|
|
14731
15235
|
}
|
|
14732
15236
|
};
|
|
14733
15237
|
|
|
@@ -14860,16 +15364,16 @@ init_esm_shims();
|
|
|
14860
15364
|
|
|
14861
15365
|
// src/workflows/pentest.ts
|
|
14862
15366
|
init_esm_shims();
|
|
14863
|
-
import { mkdir as
|
|
14864
|
-
import { join as
|
|
15367
|
+
import { mkdir as mkdir30, writeFile as writeFile30 } from "fs/promises";
|
|
15368
|
+
import { join as join69, relative as relative13 } from "path";
|
|
14865
15369
|
init_paths();
|
|
14866
15370
|
|
|
14867
15371
|
// src/pentest/findings.ts
|
|
14868
15372
|
init_esm_shims();
|
|
14869
|
-
import { existsSync as
|
|
14870
|
-
import { readFile as
|
|
14871
|
-
import { join as
|
|
14872
|
-
import { createHash as
|
|
15373
|
+
import { existsSync as existsSync25 } from "fs";
|
|
15374
|
+
import { readFile as readFile41 } from "fs/promises";
|
|
15375
|
+
import { join as join67 } from "path";
|
|
15376
|
+
import { createHash as createHash12 } from "crypto";
|
|
14873
15377
|
function createFinding(input3) {
|
|
14874
15378
|
return {
|
|
14875
15379
|
id: "",
|
|
@@ -15296,11 +15800,11 @@ function buildModuleFindings(docs, tests) {
|
|
|
15296
15800
|
return findings;
|
|
15297
15801
|
}
|
|
15298
15802
|
async function buildSecretFindings(artifactDir) {
|
|
15299
|
-
const path11 =
|
|
15300
|
-
if (!
|
|
15803
|
+
const path11 = join67(artifactDir, "secrets", "matches.txt");
|
|
15804
|
+
if (!existsSync25(path11)) {
|
|
15301
15805
|
return [];
|
|
15302
15806
|
}
|
|
15303
|
-
const matches = parseSecretMatches(await
|
|
15807
|
+
const matches = parseSecretMatches(await readFile41(path11, "utf8"));
|
|
15304
15808
|
return matches.map(
|
|
15305
15809
|
(match, index) => createFinding({
|
|
15306
15810
|
title: `Potential secret exposure match ${index + 1}`,
|
|
@@ -15433,12 +15937,12 @@ function findingFingerprint(finding) {
|
|
|
15433
15937
|
runtime_required: finding.runtime_required,
|
|
15434
15938
|
manual_follow_up: finding.manual_follow_up
|
|
15435
15939
|
});
|
|
15436
|
-
return
|
|
15940
|
+
return createHash12("sha1").update(payload).digest("hex").slice(0, 8).toUpperCase();
|
|
15437
15941
|
}
|
|
15438
15942
|
async function readNativeAuditFindings(artifactDir) {
|
|
15439
15943
|
const findings = [];
|
|
15440
|
-
const dependencyDir =
|
|
15441
|
-
const npmAudit = await readJsonMaybe(
|
|
15944
|
+
const dependencyDir = join67(artifactDir, "dependencies");
|
|
15945
|
+
const npmAudit = await readJsonMaybe(join67(dependencyDir, "npm-audit.json"));
|
|
15442
15946
|
for (const [name, vulnerability] of Object.entries(npmAudit?.vulnerabilities ?? {})) {
|
|
15443
15947
|
const via = (vulnerability.via ?? []).find((entry) => typeof entry === "object");
|
|
15444
15948
|
findings.push({
|
|
@@ -15450,7 +15954,7 @@ async function readNativeAuditFindings(artifactDir) {
|
|
|
15450
15954
|
details: via?.url ?? ""
|
|
15451
15955
|
});
|
|
15452
15956
|
}
|
|
15453
|
-
const pnpmAudit = await readJsonMaybe(
|
|
15957
|
+
const pnpmAudit = await readJsonMaybe(join67(dependencyDir, "pnpm-audit.json"));
|
|
15454
15958
|
for (const advisory of Object.values(pnpmAudit?.advisories ?? {})) {
|
|
15455
15959
|
findings.push({
|
|
15456
15960
|
package_name: advisory.module_name ?? "unknown",
|
|
@@ -15461,7 +15965,7 @@ async function readNativeAuditFindings(artifactDir) {
|
|
|
15461
15965
|
details: advisory.overview ?? ""
|
|
15462
15966
|
});
|
|
15463
15967
|
}
|
|
15464
|
-
const composerAudit = await readJsonMaybe(
|
|
15968
|
+
const composerAudit = await readJsonMaybe(join67(dependencyDir, "composer-audit.json"));
|
|
15465
15969
|
if (Array.isArray(composerAudit?.advisories)) {
|
|
15466
15970
|
for (const advisory of composerAudit.advisories) {
|
|
15467
15971
|
findings.push({
|
|
@@ -15498,11 +16002,11 @@ async function readNativeAuditFindings(artifactDir) {
|
|
|
15498
16002
|
});
|
|
15499
16003
|
}
|
|
15500
16004
|
async function readJsonMaybe(path11) {
|
|
15501
|
-
if (!
|
|
16005
|
+
if (!existsSync25(path11)) {
|
|
15502
16006
|
return null;
|
|
15503
16007
|
}
|
|
15504
16008
|
try {
|
|
15505
|
-
return JSON.parse(await
|
|
16009
|
+
return JSON.parse(await readFile41(path11, "utf8"));
|
|
15506
16010
|
} catch {
|
|
15507
16011
|
return null;
|
|
15508
16012
|
}
|
|
@@ -15599,9 +16103,9 @@ var FileCheckMapper = class {
|
|
|
15599
16103
|
|
|
15600
16104
|
// src/pentest/incremental-scanner.ts
|
|
15601
16105
|
init_esm_shims();
|
|
15602
|
-
import { readFile as
|
|
15603
|
-
import { join as
|
|
15604
|
-
import { createHash as
|
|
16106
|
+
import { readFile as readFile42 } from "fs/promises";
|
|
16107
|
+
import { join as join68 } from "path";
|
|
16108
|
+
import { createHash as createHash13 } from "crypto";
|
|
15605
16109
|
import { execa as execa3 } from "execa";
|
|
15606
16110
|
var IncrementalScanner = class {
|
|
15607
16111
|
constructor(mapper) {
|
|
@@ -15638,10 +16142,10 @@ var IncrementalScanner = class {
|
|
|
15638
16142
|
}
|
|
15639
16143
|
}
|
|
15640
16144
|
async gitDiff(projectRoot, lastRunId) {
|
|
15641
|
-
const progressPath =
|
|
16145
|
+
const progressPath = join68(projectRoot, ".paqad", "pentest", "runs", lastRunId, "progress.json");
|
|
15642
16146
|
let baseCommit;
|
|
15643
16147
|
try {
|
|
15644
|
-
const raw = await
|
|
16148
|
+
const raw = await readFile42(progressPath, "utf8");
|
|
15645
16149
|
const progress = JSON.parse(raw);
|
|
15646
16150
|
baseCommit = progress.git_commit;
|
|
15647
16151
|
} catch {
|
|
@@ -15655,10 +16159,10 @@ var IncrementalScanner = class {
|
|
|
15655
16159
|
return result.stdout.split("\n").map((f) => f.trim()).filter(Boolean);
|
|
15656
16160
|
}
|
|
15657
16161
|
async hashDiff(projectRoot, lastRunId) {
|
|
15658
|
-
const manifestPath =
|
|
16162
|
+
const manifestPath = join68(projectRoot, ".paqad", "pentest", "runs", lastRunId, "progress.json");
|
|
15659
16163
|
let fileManifest = {};
|
|
15660
16164
|
try {
|
|
15661
|
-
const raw = await
|
|
16165
|
+
const raw = await readFile42(manifestPath, "utf8");
|
|
15662
16166
|
const progress = JSON.parse(raw);
|
|
15663
16167
|
fileManifest = progress.file_hashes ?? {};
|
|
15664
16168
|
} catch {
|
|
@@ -15667,8 +16171,8 @@ var IncrementalScanner = class {
|
|
|
15667
16171
|
const changed = [];
|
|
15668
16172
|
for (const [filePath, storedHash] of Object.entries(fileManifest)) {
|
|
15669
16173
|
try {
|
|
15670
|
-
const content = await
|
|
15671
|
-
const currentHash =
|
|
16174
|
+
const content = await readFile42(join68(projectRoot, filePath), "utf8");
|
|
16175
|
+
const currentHash = createHash13("sha256").update(content).digest("hex");
|
|
15672
16176
|
if (currentHash !== storedHash) {
|
|
15673
16177
|
changed.push(filePath);
|
|
15674
16178
|
}
|
|
@@ -15680,13 +16184,13 @@ var IncrementalScanner = class {
|
|
|
15680
16184
|
}
|
|
15681
16185
|
async warnIfFullScanStale(projectRoot, thresholdDays) {
|
|
15682
16186
|
try {
|
|
15683
|
-
const runsDir =
|
|
15684
|
-
const { readdir:
|
|
15685
|
-
const runs = await
|
|
16187
|
+
const runsDir = join68(projectRoot, ".paqad", "pentest", "runs");
|
|
16188
|
+
const { readdir: readdir13 } = await import("fs/promises");
|
|
16189
|
+
const runs = await readdir13(runsDir).catch(() => []);
|
|
15686
16190
|
for (const run of runs.sort().reverse()) {
|
|
15687
|
-
const progressPath =
|
|
16191
|
+
const progressPath = join68(runsDir, run, "progress.json");
|
|
15688
16192
|
try {
|
|
15689
|
-
const raw = await
|
|
16193
|
+
const raw = await readFile42(progressPath, "utf8");
|
|
15690
16194
|
const progress = JSON.parse(raw);
|
|
15691
16195
|
if (!progress.incremental_type || progress.incremental_type === "full") {
|
|
15692
16196
|
const startedAt = new Date(progress.started_at ?? 0);
|
|
@@ -15872,8 +16376,8 @@ var PentestWorkflow = class {
|
|
|
15872
16376
|
await this.tracker.save(options.projectRoot, progress);
|
|
15873
16377
|
const artifactsDir = runArtifactsDir(options.projectRoot, progress.run_id);
|
|
15874
16378
|
const logsDir = runLogsDir(options.projectRoot, progress.run_id);
|
|
15875
|
-
await
|
|
15876
|
-
await
|
|
16379
|
+
await mkdir30(artifactsDir, { recursive: true });
|
|
16380
|
+
await mkdir30(logsDir, { recursive: true });
|
|
15877
16381
|
const blockedChecks = [];
|
|
15878
16382
|
const contextHash = await hashRelevantInputs(options.projectRoot, "pentest", {
|
|
15879
16383
|
focus_modules: focusModules
|
|
@@ -15883,8 +16387,8 @@ var PentestWorkflow = class {
|
|
|
15883
16387
|
await this.tracker.save(options.projectRoot, progress);
|
|
15884
16388
|
const docs = await loadModuleDocs(options.projectRoot, focusModules);
|
|
15885
16389
|
const tests = await loadTests(options.projectRoot, focusModules);
|
|
15886
|
-
const docsPath =
|
|
15887
|
-
const testsPath =
|
|
16390
|
+
const docsPath = join69(artifactsDir, "docs-summary.json");
|
|
16391
|
+
const testsPath = join69(artifactsDir, "tests-summary.json");
|
|
15888
16392
|
await writeJson(docsPath, docs);
|
|
15889
16393
|
await writeJson(
|
|
15890
16394
|
testsPath,
|
|
@@ -15896,7 +16400,7 @@ var PentestWorkflow = class {
|
|
|
15896
16400
|
this.tracker.markStepCompleted(
|
|
15897
16401
|
progress,
|
|
15898
16402
|
"collect-context",
|
|
15899
|
-
[
|
|
16403
|
+
[relative13(options.projectRoot, docsPath), relative13(options.projectRoot, testsPath)],
|
|
15900
16404
|
[...PENTEST_SKILLS.context].map(skillPath)
|
|
15901
16405
|
);
|
|
15902
16406
|
await this.tracker.save(options.projectRoot, progress);
|
|
@@ -15985,7 +16489,7 @@ var PentestWorkflow = class {
|
|
|
15985
16489
|
progressRunId: progress.run_id,
|
|
15986
16490
|
reportTimestamp: new Date(progress.started_at)
|
|
15987
16491
|
});
|
|
15988
|
-
const findingIndexPath =
|
|
16492
|
+
const findingIndexPath = join69(
|
|
15989
16493
|
options.projectRoot,
|
|
15990
16494
|
PATHS.PENTEST_RUNS_DIR,
|
|
15991
16495
|
progress.run_id,
|
|
@@ -15995,14 +16499,14 @@ var PentestWorkflow = class {
|
|
|
15995
16499
|
this.tracker.markStepCompleted(
|
|
15996
16500
|
progress,
|
|
15997
16501
|
"synthesize-findings",
|
|
15998
|
-
[
|
|
16502
|
+
[relative13(options.projectRoot, findingIndexPath), ...report.raw_evidence_paths],
|
|
15999
16503
|
[...PENTEST_SKILLS.normalize].map(skillPath)
|
|
16000
16504
|
);
|
|
16001
16505
|
await this.tracker.save(options.projectRoot, progress);
|
|
16002
16506
|
}
|
|
16003
16507
|
if (report === null) {
|
|
16004
16508
|
const existingSidecar = progress.sidecar_path ? await readJsonIfExists(
|
|
16005
|
-
|
|
16509
|
+
join69(options.projectRoot, progress.sidecar_path)
|
|
16006
16510
|
) : null;
|
|
16007
16511
|
report = existingSidecar;
|
|
16008
16512
|
}
|
|
@@ -16017,18 +16521,18 @@ var PentestWorkflow = class {
|
|
|
16017
16521
|
this.tracker.markStepRunning(progress, "write-report", writeHash);
|
|
16018
16522
|
await this.tracker.save(options.projectRoot, progress);
|
|
16019
16523
|
await writeJson(
|
|
16020
|
-
|
|
16524
|
+
join69(options.projectRoot, PATHS.PENTEST_RUNS_DIR, progress.run_id, "report-preview.json"),
|
|
16021
16525
|
{ report_id: report.report_id, findings: report.findings.length }
|
|
16022
16526
|
);
|
|
16023
|
-
await writeJson(
|
|
16527
|
+
await writeJson(join69(options.projectRoot, report.sidecar_path), report);
|
|
16024
16528
|
await writeJson(
|
|
16025
|
-
|
|
16529
|
+
join69(options.projectRoot, PATHS.PENTEST_RUNS_DIR, progress.run_id, "blocked-checks.json"),
|
|
16026
16530
|
report.blocked_checks
|
|
16027
16531
|
);
|
|
16028
|
-
await
|
|
16532
|
+
await mkdir30(join69(options.projectRoot, PATHS.PENTEST_DIR), { recursive: true });
|
|
16029
16533
|
const markdown = buildPentestMarkdown(report);
|
|
16030
|
-
await writeJson(
|
|
16031
|
-
await
|
|
16534
|
+
await writeJson(join69(options.projectRoot, report.sidecar_path), report);
|
|
16535
|
+
await writeFile30(join69(options.projectRoot, report.report_path), markdown);
|
|
16032
16536
|
this.tracker.markStepCompleted(
|
|
16033
16537
|
progress,
|
|
16034
16538
|
"write-report",
|
|
@@ -16055,7 +16559,7 @@ async function buildCurrentPentestReport(input3) {
|
|
|
16055
16559
|
const docs = await loadModuleDocs(input3.projectRoot, input3.focusModules);
|
|
16056
16560
|
const tests = await loadTests(input3.projectRoot, input3.focusModules);
|
|
16057
16561
|
const osvFindings = await queryOsv(input3.snapshot.packages);
|
|
16058
|
-
const osvPath =
|
|
16562
|
+
const osvPath = join69(input3.artifactsDir, "dependencies", "osv-results.json");
|
|
16059
16563
|
await writeJson(osvPath, osvFindings);
|
|
16060
16564
|
const dependencyFindings = await buildDependencyFindings(
|
|
16061
16565
|
input3.snapshot,
|
|
@@ -16064,7 +16568,7 @@ async function buildCurrentPentestReport(input3) {
|
|
|
16064
16568
|
);
|
|
16065
16569
|
const moduleFindings = buildModuleFindings(docs, tests);
|
|
16066
16570
|
const secretFindings = await buildSecretFindings(input3.artifactsDir);
|
|
16067
|
-
const runtimePayload = await readJsonIfExists(
|
|
16571
|
+
const runtimePayload = await readJsonIfExists(join69(input3.artifactsDir, "runtime", "runtime-checks.json"));
|
|
16068
16572
|
const runtimeStatus = input3.targetUrl ? runtimePayload?.reachable ? {
|
|
16069
16573
|
target_url: input3.targetUrl,
|
|
16070
16574
|
status: "reachable",
|
|
@@ -16090,8 +16594,8 @@ async function buildCurrentPentestReport(input3) {
|
|
|
16090
16594
|
...runtimeFindings
|
|
16091
16595
|
]);
|
|
16092
16596
|
const timestamp = toLocalTimestamp(input3.reportTimestamp);
|
|
16093
|
-
const reportPath =
|
|
16094
|
-
const sidecarPath =
|
|
16597
|
+
const reportPath = join69(PATHS.PENTEST_DIR, `${timestamp}.md`);
|
|
16598
|
+
const sidecarPath = join69(PATHS.PENTEST_DIR, `${timestamp}.json`);
|
|
16095
16599
|
const stack = getPrimaryStack({
|
|
16096
16600
|
routing: { domain: "coding" },
|
|
16097
16601
|
stack_profile: input3.snapshot.profile
|
|
@@ -16142,11 +16646,11 @@ async function buildCurrentPentestReport(input3) {
|
|
|
16142
16646
|
],
|
|
16143
16647
|
next_remediation_priorities: remediationPriorities(findings),
|
|
16144
16648
|
raw_evidence_paths: [
|
|
16145
|
-
|
|
16649
|
+
relative13(input3.projectRoot, osvPath),
|
|
16146
16650
|
...[
|
|
16147
|
-
|
|
16148
|
-
|
|
16149
|
-
|
|
16651
|
+
join69(PATHS.PENTEST_RUNS_DIR, input3.progressRunId, "finding-index.json"),
|
|
16652
|
+
join69(PATHS.PENTEST_RUNS_DIR, input3.progressRunId, "artifacts", "docs-summary.json"),
|
|
16653
|
+
join69(PATHS.PENTEST_RUNS_DIR, input3.progressRunId, "artifacts", "tests-summary.json")
|
|
16150
16654
|
]
|
|
16151
16655
|
]
|
|
16152
16656
|
};
|
|
@@ -16190,8 +16694,8 @@ init_esm_shims();
|
|
|
16190
16694
|
// src/workflows/pentest-retest.ts
|
|
16191
16695
|
init_esm_shims();
|
|
16192
16696
|
init_paths();
|
|
16193
|
-
import { mkdir as
|
|
16194
|
-
import { dirname as
|
|
16697
|
+
import { mkdir as mkdir31, writeFile as writeFile31 } from "fs/promises";
|
|
16698
|
+
import { dirname as dirname24, join as join70 } from "path";
|
|
16195
16699
|
var RETEST_STEPS = [
|
|
16196
16700
|
{ id: "load-source-report", title: "Load source pentest report" },
|
|
16197
16701
|
{ id: "rerun-evidence", title: "Collect fresh evidence for source findings" },
|
|
@@ -16212,7 +16716,7 @@ var PentestRetestWorkflow = class {
|
|
|
16212
16716
|
}
|
|
16213
16717
|
const normalizedSourcePath = normalizeSidecarPath(sourceReportPath);
|
|
16214
16718
|
const sourceSidecar = await readJsonIfExists(
|
|
16215
|
-
|
|
16719
|
+
join70(options.projectRoot, normalizedSourcePath)
|
|
16216
16720
|
);
|
|
16217
16721
|
if (sourceSidecar === null) {
|
|
16218
16722
|
throw new Error(`Source pentest sidecar not found at ${normalizedSourcePath}`);
|
|
@@ -16237,12 +16741,12 @@ var PentestRetestWorkflow = class {
|
|
|
16237
16741
|
if (!this.tracker.shouldSkipStep(progress, "load-source-report", sourceHash)) {
|
|
16238
16742
|
this.tracker.markStepRunning(progress, "load-source-report", sourceHash);
|
|
16239
16743
|
await this.tracker.save(options.projectRoot, progress);
|
|
16240
|
-
const sourceCopy =
|
|
16744
|
+
const sourceCopy = join70(artifactsDir, "source-report.json");
|
|
16241
16745
|
await writeJson(sourceCopy, sourceSidecar);
|
|
16242
16746
|
this.tracker.markStepCompleted(
|
|
16243
16747
|
progress,
|
|
16244
16748
|
"load-source-report",
|
|
16245
|
-
[
|
|
16749
|
+
[join70(PATHS.PENTEST_RUNS_DIR, progress.run_id, "artifacts", "source-report.json")],
|
|
16246
16750
|
[...RETEST_SKILLS.source].map(skillPath)
|
|
16247
16751
|
);
|
|
16248
16752
|
await this.tracker.save(options.projectRoot, progress);
|
|
@@ -16259,7 +16763,7 @@ var PentestRetestWorkflow = class {
|
|
|
16259
16763
|
PENTEST_RUN_ID: progress.run_id,
|
|
16260
16764
|
PENTEST_ARTIFACT_DIR: artifactsDir,
|
|
16261
16765
|
PENTEST_TARGET_URL: targetUrl ?? "",
|
|
16262
|
-
PENTEST_SOURCE_REPORT:
|
|
16766
|
+
PENTEST_SOURCE_REPORT: join70(options.projectRoot, normalizedSourcePath),
|
|
16263
16767
|
PENTEST_DB_CONNECTION_NAME: options.dbConnectionName ?? ""
|
|
16264
16768
|
};
|
|
16265
16769
|
const scriptResults = await Promise.all([
|
|
@@ -16308,8 +16812,8 @@ var PentestRetestWorkflow = class {
|
|
|
16308
16812
|
...currentReport,
|
|
16309
16813
|
report_id: toReportId("RETEST", new Date(progress.started_at)),
|
|
16310
16814
|
workflow: "pentest-retest",
|
|
16311
|
-
report_path:
|
|
16312
|
-
sidecar_path:
|
|
16815
|
+
report_path: join70(PATHS.PENTEST_RETEST_DIR, `${timestamp}-${sourceSlug}.md`),
|
|
16816
|
+
sidecar_path: join70(PATHS.PENTEST_RETEST_DIR, `${timestamp}-${sourceSlug}.json`),
|
|
16313
16817
|
source_report_path: normalizedSourcePath,
|
|
16314
16818
|
source_report_id: sourceSidecar.report_id,
|
|
16315
16819
|
findings: retestFindings,
|
|
@@ -16322,7 +16826,7 @@ var PentestRetestWorkflow = class {
|
|
|
16322
16826
|
...[...RETEST_SKILLS.source, ...RETEST_SKILLS.evaluate].map(skillPath)
|
|
16323
16827
|
]
|
|
16324
16828
|
};
|
|
16325
|
-
const findingIndexPath =
|
|
16829
|
+
const findingIndexPath = join70(
|
|
16326
16830
|
options.projectRoot,
|
|
16327
16831
|
PATHS.PENTEST_RUNS_DIR,
|
|
16328
16832
|
progress.run_id,
|
|
@@ -16332,14 +16836,14 @@ var PentestRetestWorkflow = class {
|
|
|
16332
16836
|
this.tracker.markStepCompleted(
|
|
16333
16837
|
progress,
|
|
16334
16838
|
"evaluate-source-findings",
|
|
16335
|
-
[
|
|
16839
|
+
[join70(PATHS.PENTEST_RUNS_DIR, progress.run_id, "finding-index.json")],
|
|
16336
16840
|
[...RETEST_SKILLS.evaluate].map(skillPath)
|
|
16337
16841
|
);
|
|
16338
16842
|
await this.tracker.save(options.projectRoot, progress);
|
|
16339
16843
|
}
|
|
16340
16844
|
if (retestReport === null) {
|
|
16341
16845
|
const existing = progress.sidecar_path ? await readJsonIfExists(
|
|
16342
|
-
|
|
16846
|
+
join70(options.projectRoot, progress.sidecar_path)
|
|
16343
16847
|
) : null;
|
|
16344
16848
|
retestReport = existing;
|
|
16345
16849
|
}
|
|
@@ -16353,12 +16857,12 @@ var PentestRetestWorkflow = class {
|
|
|
16353
16857
|
if (!this.tracker.shouldSkipStep(progress, "write-report", writeHash)) {
|
|
16354
16858
|
this.tracker.markStepRunning(progress, "write-report", writeHash);
|
|
16355
16859
|
await this.tracker.save(options.projectRoot, progress);
|
|
16356
|
-
await writeJson(
|
|
16357
|
-
await
|
|
16860
|
+
await writeJson(join70(options.projectRoot, retestReport.sidecar_path), retestReport);
|
|
16861
|
+
await mkdir31(dirname24(join70(options.projectRoot, retestReport.report_path)), {
|
|
16358
16862
|
recursive: true
|
|
16359
16863
|
});
|
|
16360
|
-
await
|
|
16361
|
-
|
|
16864
|
+
await writeFile31(
|
|
16865
|
+
join70(options.projectRoot, retestReport.report_path),
|
|
16362
16866
|
buildPentestMarkdown(retestReport)
|
|
16363
16867
|
);
|
|
16364
16868
|
this.tracker.markStepCompleted(
|
|
@@ -16421,8 +16925,8 @@ var PentestRetestPhase = class {
|
|
|
16421
16925
|
|
|
16422
16926
|
// src/pipeline/phases/question-answering.ts
|
|
16423
16927
|
init_esm_shims();
|
|
16424
|
-
import { mkdir as
|
|
16425
|
-
import { dirname as
|
|
16928
|
+
import { mkdir as mkdir32, rename as rename2, writeFile as writeFile32 } from "fs/promises";
|
|
16929
|
+
import { dirname as dirname25, join as join73 } from "path";
|
|
16426
16930
|
init_paths();
|
|
16427
16931
|
|
|
16428
16932
|
// src/project-knowledge/index.ts
|
|
@@ -16434,9 +16938,9 @@ init_esm_shims();
|
|
|
16434
16938
|
// src/project-knowledge/evidence-retriever.ts
|
|
16435
16939
|
init_esm_shims();
|
|
16436
16940
|
init_service();
|
|
16437
|
-
import { readFile as
|
|
16438
|
-
import { join as
|
|
16439
|
-
import
|
|
16941
|
+
import { readFile as readFile43 } from "fs/promises";
|
|
16942
|
+
import { join as join71 } from "path";
|
|
16943
|
+
import fg16 from "fast-glob";
|
|
16440
16944
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
16441
16945
|
"a",
|
|
16442
16946
|
"an",
|
|
@@ -16598,17 +17102,17 @@ var EvidenceRetriever = class {
|
|
|
16598
17102
|
async retrieveLexicalEvidence(query, keywords) {
|
|
16599
17103
|
const candidates = [];
|
|
16600
17104
|
for (const { pattern, source_class } of EVIDENCE_PATTERNS) {
|
|
16601
|
-
const paths = await
|
|
17105
|
+
const paths = await fg16(pattern, {
|
|
16602
17106
|
cwd: query.project_root,
|
|
16603
17107
|
absolute: false,
|
|
16604
17108
|
dot: true
|
|
16605
17109
|
});
|
|
16606
17110
|
for (const relativePath of paths) {
|
|
16607
|
-
const absolutePath =
|
|
17111
|
+
const absolutePath = join71(query.project_root, relativePath);
|
|
16608
17112
|
let excerpt = "";
|
|
16609
17113
|
let score = 0;
|
|
16610
17114
|
try {
|
|
16611
|
-
const content = await
|
|
17115
|
+
const content = await readFile43(absolutePath, "utf8");
|
|
16612
17116
|
score = scoreFile(relativePath, content, keywords);
|
|
16613
17117
|
if (score <= 0) {
|
|
16614
17118
|
continue;
|
|
@@ -16628,18 +17132,18 @@ var EvidenceRetriever = class {
|
|
|
16628
17132
|
|
|
16629
17133
|
// src/project-knowledge/freshness-checker.ts
|
|
16630
17134
|
init_esm_shims();
|
|
16631
|
-
import { readFile as
|
|
16632
|
-
import { join as
|
|
17135
|
+
import { readFile as readFile44, stat as stat6 } from "fs/promises";
|
|
17136
|
+
import { join as join72 } from "path";
|
|
16633
17137
|
var STALE_THRESHOLD_MS = 24 * 60 * 60 * 1e3;
|
|
16634
17138
|
var UNKNOWN_NOTE = "Documentation freshness unknown \u2014 run paqad-ai onboard to establish baseline";
|
|
16635
17139
|
var FreshnessChecker = class {
|
|
16636
17140
|
async check(projectRoot, evidencePaths) {
|
|
16637
|
-
const docProgressPath =
|
|
16638
|
-
const stackDriftPath =
|
|
17141
|
+
const docProgressPath = join72(projectRoot, ".paqad", "doc-progress.json");
|
|
17142
|
+
const stackDriftPath = join72(projectRoot, ".paqad", "stack-drift.json");
|
|
16639
17143
|
let generatedAt;
|
|
16640
17144
|
let note;
|
|
16641
17145
|
try {
|
|
16642
|
-
const raw = await
|
|
17146
|
+
const raw = await readFile44(docProgressPath, "utf8");
|
|
16643
17147
|
const parsed = JSON.parse(raw);
|
|
16644
17148
|
generatedAt = parsed.generated_at;
|
|
16645
17149
|
} catch {
|
|
@@ -16647,7 +17151,7 @@ var FreshnessChecker = class {
|
|
|
16647
17151
|
}
|
|
16648
17152
|
let driftDetected = false;
|
|
16649
17153
|
try {
|
|
16650
|
-
const raw = await
|
|
17154
|
+
const raw = await readFile44(stackDriftPath, "utf8");
|
|
16651
17155
|
const parsed = JSON.parse(raw);
|
|
16652
17156
|
driftDetected = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && Object.keys(parsed).length > 0;
|
|
16653
17157
|
} catch {
|
|
@@ -16656,7 +17160,7 @@ var FreshnessChecker = class {
|
|
|
16656
17160
|
if (generatedAt) {
|
|
16657
17161
|
const baseTime = new Date(generatedAt).getTime();
|
|
16658
17162
|
for (const relativePath of evidencePaths) {
|
|
16659
|
-
const absolutePath =
|
|
17163
|
+
const absolutePath = join72(projectRoot, relativePath);
|
|
16660
17164
|
try {
|
|
16661
17165
|
const info = await stat6(absolutePath);
|
|
16662
17166
|
const ageDiff = info.mtimeMs - baseTime;
|
|
@@ -16878,10 +17382,10 @@ var ProjectQuestionPhase = class {
|
|
|
16878
17382
|
project_root: context.project_root
|
|
16879
17383
|
});
|
|
16880
17384
|
const answerArtifactPath = PATHS.PROJECT_QUESTION_ANSWER;
|
|
16881
|
-
const target =
|
|
16882
|
-
await
|
|
17385
|
+
const target = join73(context.project_root, answerArtifactPath);
|
|
17386
|
+
await mkdir32(dirname25(target), { recursive: true });
|
|
16883
17387
|
const tmp = `${target}.tmp`;
|
|
16884
|
-
await
|
|
17388
|
+
await writeFile32(tmp, `${JSON.stringify(answer, null, 2)}
|
|
16885
17389
|
`, "utf8");
|
|
16886
17390
|
await rename2(tmp, target);
|
|
16887
17391
|
return createPassResult(
|
|
@@ -16899,8 +17403,8 @@ init_esm_shims();
|
|
|
16899
17403
|
// src/workflows/root-cause-analysis.ts
|
|
16900
17404
|
init_esm_shims();
|
|
16901
17405
|
init_paths();
|
|
16902
|
-
import { mkdir as
|
|
16903
|
-
import { dirname as
|
|
17406
|
+
import { mkdir as mkdir33, writeFile as writeFile33 } from "fs/promises";
|
|
17407
|
+
import { dirname as dirname26, join as join74 } from "path";
|
|
16904
17408
|
var DEFAULT_TITLE_SLUG = "root-cause-analysis";
|
|
16905
17409
|
var RCA_SECTIONS = [
|
|
16906
17410
|
"Summary",
|
|
@@ -16919,10 +17423,10 @@ var RootCauseAnalysisWorkflow = class {
|
|
|
16919
17423
|
async run(options) {
|
|
16920
17424
|
const title = deriveTitle(options.classification.request_text);
|
|
16921
17425
|
const filename = `${toLocalTimestamp2(/* @__PURE__ */ new Date())}-${slugify2(title) || DEFAULT_TITLE_SLUG}.md`;
|
|
16922
|
-
const relativePath =
|
|
16923
|
-
const outputPath =
|
|
16924
|
-
await
|
|
16925
|
-
await
|
|
17426
|
+
const relativePath = join74(PATHS.RCA_DIR, filename);
|
|
17427
|
+
const outputPath = join74(options.projectRoot, relativePath);
|
|
17428
|
+
await mkdir33(dirname26(outputPath), { recursive: true });
|
|
17429
|
+
await writeFile33(outputPath, buildRcaDocument(title, options.classification));
|
|
16926
17430
|
return {
|
|
16927
17431
|
output_path: relativePath,
|
|
16928
17432
|
title
|
|
@@ -17736,9 +18240,9 @@ var DatabaseQualityGate = class {
|
|
|
17736
18240
|
|
|
17737
18241
|
// src/verification/gates/documentation-freshness.ts
|
|
17738
18242
|
init_esm_shims();
|
|
17739
|
-
import { existsSync as
|
|
17740
|
-
import { readFile as
|
|
17741
|
-
import { join as
|
|
18243
|
+
import { existsSync as existsSync26 } from "fs";
|
|
18244
|
+
import { readFile as readFile45 } from "fs/promises";
|
|
18245
|
+
import { join as join75 } from "path";
|
|
17742
18246
|
|
|
17743
18247
|
// src/validators/index.ts
|
|
17744
18248
|
init_esm_shims();
|
|
@@ -17865,7 +18369,7 @@ var DocumentationFreshnessGate = class {
|
|
|
17865
18369
|
async function collectApiDocFailures(projectRoot, modules) {
|
|
17866
18370
|
const failures = [];
|
|
17867
18371
|
for (const moduleName of modules) {
|
|
17868
|
-
const modulePath =
|
|
18372
|
+
const modulePath = join75(projectRoot, "docs", "modules", moduleName);
|
|
17869
18373
|
const result = await checkApiDocs(modulePath);
|
|
17870
18374
|
if (!result.passed) {
|
|
17871
18375
|
failures.push(result.detail);
|
|
@@ -17876,7 +18380,7 @@ async function collectApiDocFailures(projectRoot, modules) {
|
|
|
17876
18380
|
async function collectIntegrationDocFailures(projectRoot, modules) {
|
|
17877
18381
|
const failures = [];
|
|
17878
18382
|
for (const moduleName of modules) {
|
|
17879
|
-
const modulePath =
|
|
18383
|
+
const modulePath = join75(projectRoot, "docs", "modules", moduleName);
|
|
17880
18384
|
const result = await checkIntegrationDocs(modulePath);
|
|
17881
18385
|
if (!result.passed) {
|
|
17882
18386
|
failures.push(result.detail);
|
|
@@ -17887,7 +18391,7 @@ async function collectIntegrationDocFailures(projectRoot, modules) {
|
|
|
17887
18391
|
async function collectErrorCatalogFailures(projectRoot, modules) {
|
|
17888
18392
|
const failures = [];
|
|
17889
18393
|
for (const moduleName of modules) {
|
|
17890
|
-
const modulePath =
|
|
18394
|
+
const modulePath = join75(projectRoot, "docs", "modules", moduleName);
|
|
17891
18395
|
const result = await checkErrorCatalog(modulePath);
|
|
17892
18396
|
if (!result.passed) {
|
|
17893
18397
|
failures.push(result.detail);
|
|
@@ -17896,10 +18400,10 @@ async function collectErrorCatalogFailures(projectRoot, modules) {
|
|
|
17896
18400
|
return failures;
|
|
17897
18401
|
}
|
|
17898
18402
|
async function checkApiDocs(modulePath) {
|
|
17899
|
-
const endpointsPath =
|
|
17900
|
-
const endpointsExists =
|
|
17901
|
-
const schemasExists =
|
|
17902
|
-
const errorCodesExists =
|
|
18403
|
+
const endpointsPath = join75(modulePath, "api", "endpoints.md");
|
|
18404
|
+
const endpointsExists = existsSync26(endpointsPath);
|
|
18405
|
+
const schemasExists = existsSync26(join75(modulePath, "api", "schemas.md"));
|
|
18406
|
+
const errorCodesExists = existsSync26(join75(modulePath, "api", "error-codes.md"));
|
|
17903
18407
|
if (!endpointsExists || !schemasExists || !errorCodesExists) {
|
|
17904
18408
|
return {
|
|
17905
18409
|
passed: false,
|
|
@@ -17910,7 +18414,7 @@ async function checkApiDocs(modulePath) {
|
|
|
17910
18414
|
].filter(Boolean).join(", ")}`
|
|
17911
18415
|
};
|
|
17912
18416
|
}
|
|
17913
|
-
const endpointsValidation = validateApiDoc(await
|
|
18417
|
+
const endpointsValidation = validateApiDoc(await readFile45(endpointsPath, "utf8"));
|
|
17914
18418
|
if (!endpointsValidation.valid) {
|
|
17915
18419
|
return {
|
|
17916
18420
|
passed: false,
|
|
@@ -17920,8 +18424,8 @@ async function checkApiDocs(modulePath) {
|
|
|
17920
18424
|
return { passed: true, detail: "API docs present" };
|
|
17921
18425
|
}
|
|
17922
18426
|
async function checkIntegrationDocs(modulePath) {
|
|
17923
|
-
const eventsExists =
|
|
17924
|
-
const contractsExists =
|
|
18427
|
+
const eventsExists = existsSync26(join75(modulePath, "integration", "events.md"));
|
|
18428
|
+
const contractsExists = existsSync26(join75(modulePath, "integration", "contracts.md"));
|
|
17925
18429
|
if (!eventsExists || !contractsExists) {
|
|
17926
18430
|
return {
|
|
17927
18431
|
passed: false,
|
|
@@ -17934,15 +18438,15 @@ async function checkIntegrationDocs(modulePath) {
|
|
|
17934
18438
|
return { passed: true, detail: "Integration docs present" };
|
|
17935
18439
|
}
|
|
17936
18440
|
async function checkErrorCatalog(modulePath) {
|
|
17937
|
-
const catalogPath =
|
|
17938
|
-
const catalogExists =
|
|
18441
|
+
const catalogPath = join75(modulePath, "error-catalog.md");
|
|
18442
|
+
const catalogExists = existsSync26(catalogPath);
|
|
17939
18443
|
if (!catalogExists) {
|
|
17940
18444
|
return {
|
|
17941
18445
|
passed: false,
|
|
17942
18446
|
detail: `Missing error-catalog.md in ${modulePath}`
|
|
17943
18447
|
};
|
|
17944
18448
|
}
|
|
17945
|
-
const validation = validateErrorCatalogMarkdown(await
|
|
18449
|
+
const validation = validateErrorCatalogMarkdown(await readFile45(catalogPath, "utf8"));
|
|
17946
18450
|
if (!validation.valid) {
|
|
17947
18451
|
return {
|
|
17948
18452
|
passed: false,
|
|
@@ -17954,8 +18458,8 @@ async function checkErrorCatalog(modulePath) {
|
|
|
17954
18458
|
function collectMissingDocs(projectRoot, modules, segments) {
|
|
17955
18459
|
return modules.map((moduleName) => ({
|
|
17956
18460
|
moduleName,
|
|
17957
|
-
path:
|
|
17958
|
-
})).filter((entry) => !
|
|
18461
|
+
path: join75(projectRoot, "docs", "modules", moduleName, ...segments)
|
|
18462
|
+
})).filter((entry) => !existsSync26(entry.path)).map((entry) => `${entry.moduleName}:${segments.join("/")}`);
|
|
17959
18463
|
}
|
|
17960
18464
|
function isStale2(input3) {
|
|
17961
18465
|
const parsed = Date.parse(input3);
|
|
@@ -18130,10 +18634,10 @@ init_esm_shims();
|
|
|
18130
18634
|
// src/pipeline/workflow-router.ts
|
|
18131
18635
|
init_esm_shims();
|
|
18132
18636
|
init_runtime_paths();
|
|
18133
|
-
import { readFile as
|
|
18134
|
-
import { existsSync as
|
|
18135
|
-
import { join as
|
|
18136
|
-
import
|
|
18637
|
+
import { readFile as readFile46 } from "fs/promises";
|
|
18638
|
+
import { existsSync as existsSync27 } from "fs";
|
|
18639
|
+
import { join as join76, relative as relative14 } from "path";
|
|
18640
|
+
import fg17 from "fast-glob";
|
|
18137
18641
|
init_project_profile();
|
|
18138
18642
|
|
|
18139
18643
|
// src/pipeline/lane-runner.ts
|
|
@@ -18160,17 +18664,17 @@ init_esm_shims();
|
|
|
18160
18664
|
|
|
18161
18665
|
// src/pipeline/stream-truncator.ts
|
|
18162
18666
|
init_esm_shims();
|
|
18163
|
-
import { appendFile, mkdir as
|
|
18164
|
-
import { join as
|
|
18667
|
+
import { appendFile, mkdir as mkdir35 } from "fs/promises";
|
|
18668
|
+
import { join as join78, dirname as dirname28 } from "path";
|
|
18165
18669
|
|
|
18166
18670
|
// src/resolver/index.ts
|
|
18167
18671
|
init_esm_shims();
|
|
18168
18672
|
|
|
18169
18673
|
// src/resolver/deduplicator.ts
|
|
18170
18674
|
init_esm_shims();
|
|
18171
|
-
import { createHash as
|
|
18172
|
-
import { readFile as
|
|
18173
|
-
import { join as
|
|
18675
|
+
import { createHash as createHash14 } from "crypto";
|
|
18676
|
+
import { readFile as readFile48, writeFile as writeFile35, mkdir as mkdir36 } from "fs/promises";
|
|
18677
|
+
import { join as join79, dirname as dirname29 } from "path";
|
|
18174
18678
|
|
|
18175
18679
|
// src/rag/index.ts
|
|
18176
18680
|
init_esm_shims();
|
|
@@ -18269,8 +18773,8 @@ init_esm_shims();
|
|
|
18269
18773
|
// src/scripts/generator.ts
|
|
18270
18774
|
init_esm_shims();
|
|
18271
18775
|
import { chmodSync as chmodSync3 } from "fs";
|
|
18272
|
-
import { mkdir as
|
|
18273
|
-
import { dirname as
|
|
18776
|
+
import { mkdir as mkdir37, writeFile as writeFile36 } from "fs/promises";
|
|
18777
|
+
import { dirname as dirname30, join as join80 } from "path";
|
|
18274
18778
|
init_runtime_paths();
|
|
18275
18779
|
|
|
18276
18780
|
// src/skills/index.ts
|
|
@@ -18279,14 +18783,14 @@ init_esm_shims();
|
|
|
18279
18783
|
// src/skills/index-generator.ts
|
|
18280
18784
|
init_esm_shims();
|
|
18281
18785
|
init_paths();
|
|
18282
|
-
import { mkdir as
|
|
18283
|
-
import { dirname as
|
|
18284
|
-
import
|
|
18786
|
+
import { mkdir as mkdir38, readFile as readFile49, writeFile as writeFile37 } from "fs/promises";
|
|
18787
|
+
import { dirname as dirname31, join as join81, relative as relative15 } from "path";
|
|
18788
|
+
import fg19 from "fast-glob";
|
|
18285
18789
|
|
|
18286
18790
|
// src/skills/loader.ts
|
|
18287
18791
|
init_esm_shims();
|
|
18288
|
-
import { readFile as
|
|
18289
|
-
import { basename as
|
|
18792
|
+
import { readFile as readFile50 } from "fs/promises";
|
|
18793
|
+
import { basename as basename11 } from "pathe";
|
|
18290
18794
|
|
|
18291
18795
|
// src/skills/trigger-evaluator.ts
|
|
18292
18796
|
init_esm_shims();
|
|
@@ -18296,8 +18800,8 @@ init_esm_shims();
|
|
|
18296
18800
|
|
|
18297
18801
|
// src/test-output/service.ts
|
|
18298
18802
|
init_esm_shims();
|
|
18299
|
-
import { readFile as
|
|
18300
|
-
import
|
|
18803
|
+
import { readFile as readFile51 } from "fs/promises";
|
|
18804
|
+
import fg20 from "fast-glob";
|
|
18301
18805
|
|
|
18302
18806
|
// src/update/index.ts
|
|
18303
18807
|
init_esm_shims();
|
|
@@ -18306,23 +18810,23 @@ init_esm_shims();
|
|
|
18306
18810
|
init_esm_shims();
|
|
18307
18811
|
init_paths();
|
|
18308
18812
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8 } from "fs";
|
|
18309
|
-
import { dirname as
|
|
18813
|
+
import { dirname as dirname32, join as join82 } from "path";
|
|
18310
18814
|
function auditPath(projectRoot) {
|
|
18311
|
-
return
|
|
18815
|
+
return join82(projectRoot, PATHS.AUDIT_LOG);
|
|
18312
18816
|
}
|
|
18313
18817
|
function ts() {
|
|
18314
18818
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
18315
18819
|
}
|
|
18316
18820
|
function appendAuditLog2(projectRoot, previous, updated) {
|
|
18317
18821
|
const path11 = auditPath(projectRoot);
|
|
18318
|
-
mkdirSync8(
|
|
18822
|
+
mkdirSync8(dirname32(path11), { recursive: true });
|
|
18319
18823
|
const line = `[${ts()}] INFO silent-update previous=${previous ?? "unknown"} updated=${updated}
|
|
18320
18824
|
`;
|
|
18321
18825
|
appendFileSync2(path11, line);
|
|
18322
18826
|
}
|
|
18323
18827
|
function appendAuditLogFailure(projectRoot, previous, target, error) {
|
|
18324
18828
|
const path11 = auditPath(projectRoot);
|
|
18325
|
-
mkdirSync8(
|
|
18829
|
+
mkdirSync8(dirname32(path11), { recursive: true });
|
|
18326
18830
|
const sanitized = error.replace(/"/g, "'");
|
|
18327
18831
|
const line = `[${ts()}] WARN silent-update-failed previous=${previous ?? "unknown"} target=${target} error="${sanitized}"
|
|
18328
18832
|
`;
|
|
@@ -18333,16 +18837,16 @@ function appendAuditLogFailure(projectRoot, previous, target, error) {
|
|
|
18333
18837
|
init_esm_shims();
|
|
18334
18838
|
init_paths();
|
|
18335
18839
|
init_project_profile();
|
|
18336
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
18337
|
-
import { mkdtemp, readdir as
|
|
18840
|
+
import { chmodSync as chmodSync4, existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync8 } from "fs";
|
|
18841
|
+
import { mkdtemp, readdir as readdir12, readFile as readFile52, rm as rm5 } from "fs/promises";
|
|
18338
18842
|
import { tmpdir } from "os";
|
|
18339
|
-
import { dirname as
|
|
18843
|
+
import { dirname as dirname33, join as join83, relative as relative16 } from "path";
|
|
18340
18844
|
var FrameworkUpdater = class {
|
|
18341
18845
|
constructor(options = {}) {
|
|
18342
18846
|
this.options = options;
|
|
18343
18847
|
}
|
|
18344
18848
|
async run(projectRoot) {
|
|
18345
|
-
const previousVersion = readText(
|
|
18849
|
+
const previousVersion = readText(join83(projectRoot, PATHS.FRAMEWORK_VERSION));
|
|
18346
18850
|
const manifest = readManifest(projectRoot);
|
|
18347
18851
|
const artifactPolicy = new Map(
|
|
18348
18852
|
manifest?.generated_artifacts.map((artifact) => [artifact.path, artifact.auto_update]) ?? []
|
|
@@ -18352,8 +18856,8 @@ var FrameworkUpdater = class {
|
|
|
18352
18856
|
const skipped = [];
|
|
18353
18857
|
const newScripts = [];
|
|
18354
18858
|
for (const candidate of candidates) {
|
|
18355
|
-
const target =
|
|
18356
|
-
const existed =
|
|
18859
|
+
const target = join83(projectRoot, candidate.path);
|
|
18860
|
+
const existed = existsSync29(target);
|
|
18357
18861
|
const autoUpdate = artifactPolicy.get(candidate.path) ?? candidate.autoUpdate;
|
|
18358
18862
|
if (existed && autoUpdate === false) {
|
|
18359
18863
|
skipped.push({
|
|
@@ -18363,8 +18867,8 @@ var FrameworkUpdater = class {
|
|
|
18363
18867
|
});
|
|
18364
18868
|
continue;
|
|
18365
18869
|
}
|
|
18366
|
-
mkdirSync9(
|
|
18367
|
-
|
|
18870
|
+
mkdirSync9(dirname33(target), { recursive: true });
|
|
18871
|
+
writeFileSync8(target, candidate.content);
|
|
18368
18872
|
if (candidate.executable === true) {
|
|
18369
18873
|
chmodSync4(target, 493);
|
|
18370
18874
|
}
|
|
@@ -18373,9 +18877,9 @@ var FrameworkUpdater = class {
|
|
|
18373
18877
|
newScripts.push(candidate.path);
|
|
18374
18878
|
}
|
|
18375
18879
|
}
|
|
18376
|
-
mkdirSync9(
|
|
18377
|
-
|
|
18378
|
-
|
|
18880
|
+
mkdirSync9(dirname33(join83(projectRoot, PATHS.FRAMEWORK_VERSION)), { recursive: true });
|
|
18881
|
+
writeFileSync8(
|
|
18882
|
+
join83(projectRoot, PATHS.FRAMEWORK_VERSION),
|
|
18379
18883
|
`version=${VERSION}
|
|
18380
18884
|
updated_at=${(/* @__PURE__ */ new Date()).toISOString()}
|
|
18381
18885
|
`
|
|
@@ -18398,7 +18902,7 @@ updated_at=${(/* @__PURE__ */ new Date()).toISOString()}
|
|
|
18398
18902
|
if (profile === null) {
|
|
18399
18903
|
throw new Error("Cannot update framework-managed artifacts without a project profile");
|
|
18400
18904
|
}
|
|
18401
|
-
const tempRoot = await mkdtemp(
|
|
18905
|
+
const tempRoot = await mkdtemp(join83(tmpdir(), "paqad-ai-update-"));
|
|
18402
18906
|
try {
|
|
18403
18907
|
const result = await new OnboardingOrchestrator().run({
|
|
18404
18908
|
projectRoot: tempRoot,
|
|
@@ -18419,8 +18923,8 @@ updated_at=${(/* @__PURE__ */ new Date()).toISOString()}
|
|
|
18419
18923
|
}
|
|
18420
18924
|
};
|
|
18421
18925
|
function readManifest(projectRoot) {
|
|
18422
|
-
const path11 =
|
|
18423
|
-
if (!
|
|
18926
|
+
const path11 = join83(projectRoot, PATHS.ONBOARDING_MANIFEST);
|
|
18927
|
+
if (!existsSync29(path11)) {
|
|
18424
18928
|
return null;
|
|
18425
18929
|
}
|
|
18426
18930
|
return JSON.parse(readFileSync18(path11, "utf8"));
|
|
@@ -18429,7 +18933,7 @@ function readProfile(projectRoot) {
|
|
|
18429
18933
|
return readProjectProfile(projectRoot);
|
|
18430
18934
|
}
|
|
18431
18935
|
function readText(path11) {
|
|
18432
|
-
if (!
|
|
18936
|
+
if (!existsSync29(path11)) {
|
|
18433
18937
|
return null;
|
|
18434
18938
|
}
|
|
18435
18939
|
const raw = readFileSync18(path11, "utf8");
|
|
@@ -18444,22 +18948,22 @@ async function collectFiles(root, generated, manifest) {
|
|
|
18444
18948
|
return Promise.all(
|
|
18445
18949
|
paths.map(async (file) => ({
|
|
18446
18950
|
path: file,
|
|
18447
|
-
content: await
|
|
18951
|
+
content: await readFile52(join83(root, file), "utf8"),
|
|
18448
18952
|
autoUpdate: artifactPolicy.get(file)?.auto_update ?? true,
|
|
18449
18953
|
executable: artifactPolicy.get(file)?.executable ?? file.startsWith("scripts/")
|
|
18450
18954
|
}))
|
|
18451
18955
|
);
|
|
18452
18956
|
}
|
|
18453
18957
|
async function walk4(root, current = root) {
|
|
18454
|
-
const entries = await
|
|
18958
|
+
const entries = await readdir12(current, { withFileTypes: true });
|
|
18455
18959
|
const files = [];
|
|
18456
18960
|
for (const entry of entries) {
|
|
18457
|
-
const absolute =
|
|
18961
|
+
const absolute = join83(current, entry.name);
|
|
18458
18962
|
if (entry.isDirectory()) {
|
|
18459
18963
|
files.push(...await walk4(root, absolute));
|
|
18460
18964
|
continue;
|
|
18461
18965
|
}
|
|
18462
|
-
files.push(
|
|
18966
|
+
files.push(relative16(root, absolute));
|
|
18463
18967
|
}
|
|
18464
18968
|
return files.sort();
|
|
18465
18969
|
}
|
|
@@ -18489,7 +18993,7 @@ init_pattern_suggester();
|
|
|
18489
18993
|
|
|
18490
18994
|
// src/patterns/pattern-cli.ts
|
|
18491
18995
|
init_esm_shims();
|
|
18492
|
-
import { writeFile as
|
|
18996
|
+
import { writeFile as writeFile38 } from "fs/promises";
|
|
18493
18997
|
var STALENESS_THRESHOLD_DAYS2 = 180;
|
|
18494
18998
|
var PatternCli = class {
|
|
18495
18999
|
constructor(store) {
|
|
@@ -18523,7 +19027,7 @@ var PatternCli = class {
|
|
|
18523
19027
|
async exportPatterns(outputPath, format) {
|
|
18524
19028
|
const patterns = await this.store.list();
|
|
18525
19029
|
if (format === "json") {
|
|
18526
|
-
await
|
|
19030
|
+
await writeFile38(outputPath, JSON.stringify(patterns, null, 2), "utf8");
|
|
18527
19031
|
} else {
|
|
18528
19032
|
const lines = ["# Pattern Library Export\n"];
|
|
18529
19033
|
for (const p of patterns) {
|
|
@@ -18540,7 +19044,7 @@ ${p.solution}
|
|
|
18540
19044
|
`);
|
|
18541
19045
|
lines.push("---\n");
|
|
18542
19046
|
}
|
|
18543
|
-
await
|
|
19047
|
+
await writeFile38(outputPath, lines.join("\n"), "utf8");
|
|
18544
19048
|
}
|
|
18545
19049
|
console.log(`Exported ${patterns.length} pattern(s) to ${outputPath}`);
|
|
18546
19050
|
}
|
|
@@ -18553,7 +19057,7 @@ init_esm_shims();
|
|
|
18553
19057
|
init_esm_shims();
|
|
18554
19058
|
|
|
18555
19059
|
// src/index.ts
|
|
18556
|
-
var VERSION = "0.3.
|
|
19060
|
+
var VERSION = "0.3.3";
|
|
18557
19061
|
|
|
18558
19062
|
// src/cli/commands/capabilities.ts
|
|
18559
19063
|
init_esm_shims();
|
|
@@ -18592,7 +19096,7 @@ function requireProfile(projectRoot) {
|
|
|
18592
19096
|
|
|
18593
19097
|
// src/cli/commands/compliance.ts
|
|
18594
19098
|
init_esm_shims();
|
|
18595
|
-
import { readFile as
|
|
19099
|
+
import { readFile as readFile53, stat as stat7 } from "fs/promises";
|
|
18596
19100
|
import path10 from "path";
|
|
18597
19101
|
import { Command as Command2 } from "commander";
|
|
18598
19102
|
function resolveIndexPath2(explicitPath, spec) {
|
|
@@ -18634,7 +19138,7 @@ function createComplianceCommand() {
|
|
|
18634
19138
|
const indexPath = resolveIndexPath2(options.indexPath, options.spec);
|
|
18635
19139
|
const specPath = path10.resolve(options.projectRoot, options.spec);
|
|
18636
19140
|
const relativeSpec = path10.relative(options.projectRoot, specPath);
|
|
18637
|
-
const specMarkdown = await
|
|
19141
|
+
const specMarkdown = await readFile53(specPath, "utf8");
|
|
18638
19142
|
const review = await loadSpecReviewReport({
|
|
18639
19143
|
project_root: options.projectRoot,
|
|
18640
19144
|
spec_file: relativeSpec
|
|
@@ -18655,7 +19159,7 @@ function createComplianceCommand() {
|
|
|
18655
19159
|
command.command("review <specFile>").description("Run deterministic spec-quality review and persist the review report").option("--project-root <path>", "Project root", process.cwd()).option("--json", "Print JSON instead of a human-readable summary").action(async (specFile, options) => {
|
|
18656
19160
|
const specPath = path10.resolve(options.projectRoot, specFile);
|
|
18657
19161
|
const relativeSpec = path10.relative(options.projectRoot, specPath);
|
|
18658
|
-
const specMarkdown = await
|
|
19162
|
+
const specMarkdown = await readFile53(specPath, "utf8");
|
|
18659
19163
|
const previousReport = await loadSpecReviewReport({
|
|
18660
19164
|
project_root: options.projectRoot,
|
|
18661
19165
|
spec_file: relativeSpec
|
|
@@ -19003,8 +19507,8 @@ function createInstallCommand() {
|
|
|
19003
19507
|
|
|
19004
19508
|
// src/cli/commands/onboard.ts
|
|
19005
19509
|
init_esm_shims();
|
|
19006
|
-
import { mkdirSync as mkdirSync10, writeFileSync as
|
|
19007
|
-
import { join as
|
|
19510
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
19511
|
+
import { join as join84 } from "path";
|
|
19008
19512
|
import { Command as Command5 } from "commander";
|
|
19009
19513
|
|
|
19010
19514
|
// src/cli/ui/banner.ts
|
|
@@ -19087,10 +19591,10 @@ function createOnboardCommand() {
|
|
|
19087
19591
|
);
|
|
19088
19592
|
}
|
|
19089
19593
|
function writeNextStepsFile(projectRoot) {
|
|
19090
|
-
const paqadDir =
|
|
19594
|
+
const paqadDir = join84(projectRoot, ".paqad");
|
|
19091
19595
|
mkdirSync10(paqadDir, { recursive: true });
|
|
19092
|
-
|
|
19093
|
-
|
|
19596
|
+
writeFileSync9(
|
|
19597
|
+
join84(paqadDir, "next-steps.md"),
|
|
19094
19598
|
[
|
|
19095
19599
|
"# Next Steps",
|
|
19096
19600
|
"",
|
|
@@ -19695,8 +20199,8 @@ function createRagCommand() {
|
|
|
19695
20199
|
// src/cli/commands/refresh.ts
|
|
19696
20200
|
init_esm_shims();
|
|
19697
20201
|
import { Command as Command9 } from "commander";
|
|
19698
|
-
import { existsSync as
|
|
19699
|
-
import { join as
|
|
20202
|
+
import { existsSync as existsSync30, readFileSync as readFileSync20, writeFileSync as writeFileSync10 } from "fs";
|
|
20203
|
+
import { join as join85 } from "path";
|
|
19700
20204
|
init_paths();
|
|
19701
20205
|
init_domain();
|
|
19702
20206
|
init_project_profile();
|
|
@@ -19765,9 +20269,9 @@ function resolveRefreshStack(value) {
|
|
|
19765
20269
|
return value !== void 0 && STACKS.includes(value) ? value : null;
|
|
19766
20270
|
}
|
|
19767
20271
|
function writeRefreshDrift(projectRoot, refreshDrift) {
|
|
19768
|
-
const path11 =
|
|
20272
|
+
const path11 = join85(projectRoot, PATHS.STACK_DRIFT);
|
|
19769
20273
|
const current = readExistingJson(path11);
|
|
19770
|
-
|
|
20274
|
+
writeFileSync10(path11, `${JSON.stringify({ ...current ?? {}, ...refreshDrift }, null, 2)}
|
|
19771
20275
|
`);
|
|
19772
20276
|
}
|
|
19773
20277
|
function readExistingJson(path11) {
|
|
@@ -19781,8 +20285,8 @@ function resolveChangedFiles(projectRoot, contextChangedFiles) {
|
|
|
19781
20285
|
if (contextChangedFiles.length > 0) {
|
|
19782
20286
|
return [...new Set(contextChangedFiles)].sort();
|
|
19783
20287
|
}
|
|
19784
|
-
const trackedPath =
|
|
19785
|
-
if (!
|
|
20288
|
+
const trackedPath = join85(projectRoot, PATHS.CHANGED_FILES);
|
|
20289
|
+
if (!existsSync30(trackedPath)) {
|
|
19786
20290
|
return [];
|
|
19787
20291
|
}
|
|
19788
20292
|
try {
|