paqad-ai 1.59.0 → 1.60.0
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/CHANGELOG.md +16 -0
- package/dist/cli/index.js +356 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/{feature-development-policy-BU3ikY71.d.ts → feature-development-policy-C-X0Wwyb.d.ts} +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +30 -8
- package/dist/index.js.map +1 -1
- package/dist/kernel/gate.js +15 -1
- package/dist/kernel/gate.js.map +1 -1
- package/dist/rule-scripts/index.js +14 -1
- package/dist/rule-scripts/index.js.map +1 -1
- package/dist/stage-evidence/live-writer.d.ts +2 -2
- package/dist/stage-evidence/live-writer.js +14 -1
- package/dist/stage-evidence/live-writer.js.map +1 -1
- package/dist/stage-evidence/marker-parse.d.ts +2 -2
- package/dist/stage-evidence/marker-parse.js +14 -1
- package/dist/stage-evidence/marker-parse.js.map +1 -1
- package/dist/stage-evidence/narration.d.ts +2 -2
- package/dist/stage-evidence/narration.js +14 -1
- package/dist/stage-evidence/narration.js.map +1 -1
- package/dist/{stages-B2ozdF12.d.ts → stages-DUIvMjp6.d.ts} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# paqad-ai
|
|
2
2
|
|
|
3
|
+
## 1.60.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2b2ee2c: Planning now sees the codebase: on the feature-development route, the background context
|
|
8
|
+
worker composes a token-capped `## Existing surface` section into the session-context
|
|
9
|
+
artifact. It lists the exported symbols that already exist for the files/modules the prompt
|
|
10
|
+
and working set implicate — as signature cards (`name(signature) — file:line · called from N
|
|
11
|
+
places · module`) ranked by the repo-map's structural importance (PageRank) — so the model
|
|
12
|
+
reuses what exists instead of rewriting it. Signatures and caller counts come from the
|
|
13
|
+
code-knowledge index when present, falling back to name-only cards otherwise. The section is
|
|
14
|
+
budget-capped (config `existing_surface_tokens`, default 1000) with an honest truncation
|
|
15
|
+
line, appears only for feature-development (every other route stays token-neutral), and rides
|
|
16
|
+
the existing artifact so Codex/Gemini/advisory hosts get it through the same file. This gives
|
|
17
|
+
the built-but-unconsumed repo-map its first live consumer.
|
|
18
|
+
|
|
3
19
|
## 1.59.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/cli/index.js
CHANGED
|
@@ -359,6 +359,7 @@ function defaultIntelligenceConfig() {
|
|
|
359
359
|
rag_relief_floor: 0.35,
|
|
360
360
|
rag_top_n: 20,
|
|
361
361
|
rag_max_file_size: 153600,
|
|
362
|
+
existing_surface_tokens: DEFAULT_EXISTING_SURFACE_TOKENS,
|
|
362
363
|
benchmark_gates: { ...DEFAULT_BENCHMARK_GATES },
|
|
363
364
|
benchmark_eval: { ...DEFAULT_BENCHMARK_EVAL },
|
|
364
365
|
adaptive_retrieval: {
|
|
@@ -384,6 +385,7 @@ function normalizeIntelligenceConfig(input3) {
|
|
|
384
385
|
rag_relief_floor: input3.rag_relief_floor ?? defaults.rag_relief_floor,
|
|
385
386
|
rag_top_n: input3.rag_top_n ?? defaults.rag_top_n,
|
|
386
387
|
rag_max_file_size: input3.rag_max_file_size ?? defaults.rag_max_file_size,
|
|
388
|
+
existing_surface_tokens: input3.existing_surface_tokens ?? defaults.existing_surface_tokens,
|
|
387
389
|
rag_base_branch: input3.rag_base_branch ?? defaults.rag_base_branch,
|
|
388
390
|
benchmark_gates: {
|
|
389
391
|
...DEFAULT_BENCHMARK_GATES,
|
|
@@ -421,7 +423,7 @@ function normalizeIntelligenceConfig(input3) {
|
|
|
421
423
|
}
|
|
422
424
|
return normalized;
|
|
423
425
|
}
|
|
424
|
-
var EMBEDDING_PROVIDERS, LOCAL_EMBEDDING_MODELS, DEFAULT_LOCAL_EMBEDDING_MODEL, DEFAULT_BENCHMARK_EVAL, DEFAULT_ADAPTIVE_RETRIEVAL, DEFAULT_RERANKING, DEFAULT_METADATA_FILTERS, DEFAULT_ACTION_ROUTING, DEFAULT_BENCHMARK_GATES;
|
|
426
|
+
var EMBEDDING_PROVIDERS, LOCAL_EMBEDDING_MODELS, DEFAULT_LOCAL_EMBEDDING_MODEL, DEFAULT_BENCHMARK_EVAL, DEFAULT_ADAPTIVE_RETRIEVAL, DEFAULT_RERANKING, DEFAULT_METADATA_FILTERS, DEFAULT_ACTION_ROUTING, DEFAULT_EXISTING_SURFACE_TOKENS, DEFAULT_BENCHMARK_GATES;
|
|
425
427
|
var init_project_intelligence = __esm({
|
|
426
428
|
"src/core/project-intelligence.ts"() {
|
|
427
429
|
"use strict";
|
|
@@ -461,6 +463,7 @@ var init_project_intelligence = __esm({
|
|
|
461
463
|
DEFAULT_ACTION_ROUTING = {
|
|
462
464
|
enabled: false
|
|
463
465
|
};
|
|
466
|
+
DEFAULT_EXISTING_SURFACE_TOKENS = 1e3;
|
|
464
467
|
DEFAULT_BENCHMARK_GATES = {
|
|
465
468
|
hit_at_5_improvement_pct: 20,
|
|
466
469
|
task_success_rate_improvement_pct: 10,
|
|
@@ -665,7 +668,8 @@ function resolveFrameworkConfigFromMap(raw) {
|
|
|
665
668
|
rag_relief_floor: rn("rag_relief_floor"),
|
|
666
669
|
rag_top_n: rn("rag_top_n"),
|
|
667
670
|
rag_max_file_size: rn("rag_max_file_size"),
|
|
668
|
-
rag_base_branch: raw.get("rag_base_branch")?.trim() || void 0
|
|
671
|
+
rag_base_branch: raw.get("rag_base_branch")?.trim() || void 0,
|
|
672
|
+
existing_surface_tokens: rn("existing_surface_tokens")
|
|
669
673
|
});
|
|
670
674
|
return {
|
|
671
675
|
paqad: { enabled: rb("paqad_enable") },
|
|
@@ -1029,6 +1033,11 @@ function frameworkOverridesToFlat(overrides) {
|
|
|
1029
1033
|
put("rag_top_n", i.rag_top_n, d.intelligence.rag_top_n);
|
|
1030
1034
|
put("rag_max_file_size", i.rag_max_file_size, d.intelligence.rag_max_file_size);
|
|
1031
1035
|
put("rag_base_branch", i.rag_base_branch, d.intelligence.rag_base_branch);
|
|
1036
|
+
put(
|
|
1037
|
+
"existing_surface_tokens",
|
|
1038
|
+
i.existing_surface_tokens,
|
|
1039
|
+
d.intelligence.existing_surface_tokens
|
|
1040
|
+
);
|
|
1032
1041
|
}
|
|
1033
1042
|
if (overrides.strictness) {
|
|
1034
1043
|
const s = overrides.strictness;
|
|
@@ -1388,6 +1397,15 @@ var init_framework_config = __esm({
|
|
|
1388
1397
|
section: "Intelligence / RAG",
|
|
1389
1398
|
comment: "Base branch for branch-aware RAG. Unset auto-detects main->master."
|
|
1390
1399
|
},
|
|
1400
|
+
{
|
|
1401
|
+
key: "existing_surface_tokens",
|
|
1402
|
+
env: "PAQAD_EXISTING_SURFACE_TOKENS",
|
|
1403
|
+
type: "number",
|
|
1404
|
+
default: 1e3,
|
|
1405
|
+
group: "rag",
|
|
1406
|
+
section: "Intelligence / RAG",
|
|
1407
|
+
comment: 'Token budget for the feature-development "Existing surface" planning digest (existing symbols the model should reuse). Cards drop by rank past this budget.'
|
|
1408
|
+
},
|
|
1391
1409
|
// ── models group ───────────────────────────────────────────────────────
|
|
1392
1410
|
{
|
|
1393
1411
|
key: "research_depth",
|
|
@@ -1640,7 +1658,8 @@ var init_framework_config = __esm({
|
|
|
1640
1658
|
"rag_relief_floor",
|
|
1641
1659
|
"rag_top_n",
|
|
1642
1660
|
"rag_max_file_size",
|
|
1643
|
-
"rag_base_branch"
|
|
1661
|
+
"rag_base_branch",
|
|
1662
|
+
"existing_surface_tokens"
|
|
1644
1663
|
]
|
|
1645
1664
|
},
|
|
1646
1665
|
{
|
|
@@ -3638,6 +3657,7 @@ var init_project_profile_schema = __esm({
|
|
|
3638
3657
|
rag_top_n: { type: "integer", minimum: 1 },
|
|
3639
3658
|
rag_max_file_size: { type: "integer", minimum: 1 },
|
|
3640
3659
|
rag_base_branch: { type: "string" },
|
|
3660
|
+
existing_surface_tokens: { type: "integer", minimum: 1 },
|
|
3641
3661
|
benchmark_gates: {
|
|
3642
3662
|
type: "object",
|
|
3643
3663
|
additionalProperties: false,
|
|
@@ -25067,10 +25087,12 @@ ${blocks}
|
|
|
25067
25087
|
async function writeRuleContext(projectRoot, options = {}) {
|
|
25068
25088
|
const loadRules = options.loadRules ?? true;
|
|
25069
25089
|
const store = loadRules ? await readCompiledRules(projectRoot) : null;
|
|
25090
|
+
const existingSurfaceSection = loadRules ? options.existingSurfaceSection?.trim() ?? "" : "";
|
|
25070
25091
|
const memorySection = options.memorySection?.trim() ?? "";
|
|
25071
25092
|
const retrievalSection = options.retrievalSection?.trim() ?? "";
|
|
25072
25093
|
const driftSection = options.driftSection?.trim() ?? "";
|
|
25073
|
-
if (!store && !memorySection && !retrievalSection && !driftSection)
|
|
25094
|
+
if (!store && !existingSurfaceSection && !memorySection && !retrievalSection && !driftSection)
|
|
25095
|
+
return null;
|
|
25074
25096
|
let markdown = "";
|
|
25075
25097
|
if (store) {
|
|
25076
25098
|
const changedPaths = (await loadChangeEvidence(projectRoot)).files;
|
|
@@ -25082,7 +25104,7 @@ ${DECISION_PAUSE_REMINDER}
|
|
|
25082
25104
|
`;
|
|
25083
25105
|
}
|
|
25084
25106
|
}
|
|
25085
|
-
for (const section of [memorySection, retrievalSection, driftSection]) {
|
|
25107
|
+
for (const section of [existingSurfaceSection, memorySection, retrievalSection, driftSection]) {
|
|
25086
25108
|
if (section) {
|
|
25087
25109
|
markdown = markdown ? `${markdown}
|
|
25088
25110
|
${section}
|
|
@@ -30338,7 +30360,7 @@ init_cancelled_error();
|
|
|
30338
30360
|
init_events();
|
|
30339
30361
|
|
|
30340
30362
|
// src/index.ts
|
|
30341
|
-
var VERSION = "1.
|
|
30363
|
+
var VERSION = "1.60.0";
|
|
30342
30364
|
|
|
30343
30365
|
// src/cli/commands/audit.ts
|
|
30344
30366
|
init_esm_shims();
|
|
@@ -33251,7 +33273,8 @@ var FIELD_CHECKS = {
|
|
|
33251
33273
|
rag_similarity_threshold: (value) => typeof value === "number" && value >= 0 && value <= 1 ? null : "Expected a number between 0 and 1.",
|
|
33252
33274
|
rag_top_n: (value) => typeof value === "number" && Number.isInteger(value) && value > 0 ? null : "Expected a positive integer.",
|
|
33253
33275
|
rag_max_file_size: (value) => typeof value === "number" && Number.isInteger(value) && value > 0 ? null : "Expected a positive integer.",
|
|
33254
|
-
rag_base_branch: (value) => typeof value === "string" ? null : "Expected a string."
|
|
33276
|
+
rag_base_branch: (value) => typeof value === "string" ? null : "Expected a string.",
|
|
33277
|
+
existing_surface_tokens: (value) => typeof value === "number" && Number.isInteger(value) && value > 0 ? null : "Expected a positive integer."
|
|
33255
33278
|
};
|
|
33256
33279
|
function putRagConfig(projectRoot, candidate) {
|
|
33257
33280
|
if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) {
|
|
@@ -42488,6 +42511,7 @@ var KNOB_CONSUMERS = {
|
|
|
42488
42511
|
rag_top_n: "RAG retrieval depth",
|
|
42489
42512
|
rag_max_file_size: "RAG index build",
|
|
42490
42513
|
rag_base_branch: "branch-aware RAG index",
|
|
42514
|
+
existing_surface_tokens: "existing-surface planning digest",
|
|
42491
42515
|
research_depth: NOTHING,
|
|
42492
42516
|
model_default: "model selection (skills/model-selector)",
|
|
42493
42517
|
model_reasoning: "model routing (budget optimizer)",
|
|
@@ -42659,8 +42683,8 @@ function createDecisionCommand() {
|
|
|
42659
42683
|
// src/cli/commands/rag.ts
|
|
42660
42684
|
init_esm_shims();
|
|
42661
42685
|
init_project_intelligence();
|
|
42662
|
-
import { readFileSync as
|
|
42663
|
-
import { isAbsolute as isAbsolute11, join as
|
|
42686
|
+
import { readFileSync as readFileSync104 } from "fs";
|
|
42687
|
+
import { isAbsolute as isAbsolute11, join as join208 } from "path";
|
|
42664
42688
|
import { confirm, input as input2, select as select3 } from "@inquirer/prompts";
|
|
42665
42689
|
import { Command as Command28 } from "commander";
|
|
42666
42690
|
|
|
@@ -42996,6 +43020,293 @@ ${lines}
|
|
|
42996
43020
|
`;
|
|
42997
43021
|
}
|
|
42998
43022
|
|
|
43023
|
+
// src/context/existing-surface.ts
|
|
43024
|
+
init_esm_shims();
|
|
43025
|
+
import { readFileSync as readFileSync101 } from "fs";
|
|
43026
|
+
import { join as join204 } from "path";
|
|
43027
|
+
init_project_intelligence();
|
|
43028
|
+
|
|
43029
|
+
// src/rag/repo-map.ts
|
|
43030
|
+
init_esm_shims();
|
|
43031
|
+
var PAGERANK_DAMPING = 0.85;
|
|
43032
|
+
function pageRank(seedNodes, edges, options = {}) {
|
|
43033
|
+
const damping = options.damping ?? PAGERANK_DAMPING;
|
|
43034
|
+
const iterations = options.iterations ?? 50;
|
|
43035
|
+
const tolerance = options.tolerance ?? 1e-6;
|
|
43036
|
+
const nodes = new Set(seedNodes);
|
|
43037
|
+
for (const edge of edges) {
|
|
43038
|
+
nodes.add(edge.from);
|
|
43039
|
+
nodes.add(edge.to);
|
|
43040
|
+
}
|
|
43041
|
+
const nodeList = [...nodes];
|
|
43042
|
+
const n = nodeList.length;
|
|
43043
|
+
if (n === 0) {
|
|
43044
|
+
return /* @__PURE__ */ new Map();
|
|
43045
|
+
}
|
|
43046
|
+
const outLinks = /* @__PURE__ */ new Map();
|
|
43047
|
+
for (const edge of edges) {
|
|
43048
|
+
if (edge.from === edge.to) {
|
|
43049
|
+
continue;
|
|
43050
|
+
}
|
|
43051
|
+
const list = outLinks.get(edge.from) ?? [];
|
|
43052
|
+
list.push(edge.to);
|
|
43053
|
+
outLinks.set(edge.from, list);
|
|
43054
|
+
}
|
|
43055
|
+
let rank = new Map(nodeList.map((node) => [node, 1 / n]));
|
|
43056
|
+
const base = (1 - damping) / n;
|
|
43057
|
+
for (let iteration = 0; iteration < iterations; iteration++) {
|
|
43058
|
+
const next = new Map(nodeList.map((node) => [node, base]));
|
|
43059
|
+
let danglingMass = 0;
|
|
43060
|
+
for (const node of nodeList) {
|
|
43061
|
+
const links = outLinks.get(node);
|
|
43062
|
+
if (!links || links.length === 0) {
|
|
43063
|
+
danglingMass += rank.get(node) ?? 0;
|
|
43064
|
+
}
|
|
43065
|
+
}
|
|
43066
|
+
const danglingShare = damping * danglingMass / n;
|
|
43067
|
+
for (const node of nodeList) {
|
|
43068
|
+
if (danglingShare > 0) {
|
|
43069
|
+
next.set(node, (next.get(node) ?? 0) + danglingShare);
|
|
43070
|
+
}
|
|
43071
|
+
const links = outLinks.get(node);
|
|
43072
|
+
if (!links || links.length === 0) {
|
|
43073
|
+
continue;
|
|
43074
|
+
}
|
|
43075
|
+
const contribution = damping * (rank.get(node) ?? 0) / links.length;
|
|
43076
|
+
for (const target of links) {
|
|
43077
|
+
next.set(target, (next.get(target) ?? 0) + contribution);
|
|
43078
|
+
}
|
|
43079
|
+
}
|
|
43080
|
+
let delta = 0;
|
|
43081
|
+
for (const node of nodeList) {
|
|
43082
|
+
delta += Math.abs((next.get(node) ?? 0) - (rank.get(node) ?? 0));
|
|
43083
|
+
}
|
|
43084
|
+
rank = next;
|
|
43085
|
+
if (delta < tolerance) {
|
|
43086
|
+
break;
|
|
43087
|
+
}
|
|
43088
|
+
}
|
|
43089
|
+
return rank;
|
|
43090
|
+
}
|
|
43091
|
+
var DEFAULT_REPO_MAP_TOKEN_BUDGET = 1500;
|
|
43092
|
+
var MAX_SYMBOLS_PER_FILE = 6;
|
|
43093
|
+
function estimateTokens(text) {
|
|
43094
|
+
return Math.ceil(text.length / 4);
|
|
43095
|
+
}
|
|
43096
|
+
function formatEntryLine2(entry) {
|
|
43097
|
+
const parts = [`- \`${entry.path}\``];
|
|
43098
|
+
if (entry.module) {
|
|
43099
|
+
parts.push(`\xB7 ${entry.module}`);
|
|
43100
|
+
}
|
|
43101
|
+
if (entry.symbols.length > 0) {
|
|
43102
|
+
parts.push(`\xB7 ${entry.symbols.slice(0, MAX_SYMBOLS_PER_FILE).join(", ")}`);
|
|
43103
|
+
}
|
|
43104
|
+
return parts.join(" ");
|
|
43105
|
+
}
|
|
43106
|
+
function buildRepoMap(files, edges, options = {}) {
|
|
43107
|
+
const tokenBudget = options.tokenBudget ?? DEFAULT_REPO_MAP_TOKEN_BUDGET;
|
|
43108
|
+
const ranks = pageRank(
|
|
43109
|
+
files.map((file) => file.path),
|
|
43110
|
+
edges
|
|
43111
|
+
);
|
|
43112
|
+
const entries = files.map((file) => ({
|
|
43113
|
+
path: file.path,
|
|
43114
|
+
module: file.module,
|
|
43115
|
+
symbols: file.symbols ?? [],
|
|
43116
|
+
rank: ranks.get(file.path) ?? 0
|
|
43117
|
+
})).sort((left, right) => {
|
|
43118
|
+
if (right.rank !== left.rank) {
|
|
43119
|
+
return right.rank - left.rank;
|
|
43120
|
+
}
|
|
43121
|
+
return left.path < right.path ? -1 : left.path > right.path ? 1 : 0;
|
|
43122
|
+
});
|
|
43123
|
+
if (entries.length === 0) {
|
|
43124
|
+
return { entries, skeleton: "", truncated: false };
|
|
43125
|
+
}
|
|
43126
|
+
const header = `## Repo map \u2014 ${entries.length} files ranked by structural importance
|
|
43127
|
+
> Embedding-free orientation. Use it to decide where to read or grep; verify against the live files.
|
|
43128
|
+
`;
|
|
43129
|
+
let tokens = estimateTokens(header);
|
|
43130
|
+
const lines = [];
|
|
43131
|
+
let truncated = false;
|
|
43132
|
+
for (const entry of entries) {
|
|
43133
|
+
const line = formatEntryLine2(entry);
|
|
43134
|
+
const lineTokens = estimateTokens(line) + 1;
|
|
43135
|
+
if (lines.length > 0 && tokens + lineTokens > tokenBudget) {
|
|
43136
|
+
truncated = true;
|
|
43137
|
+
break;
|
|
43138
|
+
}
|
|
43139
|
+
lines.push(line);
|
|
43140
|
+
tokens += lineTokens;
|
|
43141
|
+
}
|
|
43142
|
+
const body = truncated ? `${lines.join("\n")}
|
|
43143
|
+
\u2026[repo map truncated to fit the token budget]` : lines.join("\n");
|
|
43144
|
+
return { entries, skeleton: `${header}
|
|
43145
|
+
${body}
|
|
43146
|
+
`, truncated };
|
|
43147
|
+
}
|
|
43148
|
+
async function buildProjectRepoMap(projectRoot, options) {
|
|
43149
|
+
const edges = await scanImports({
|
|
43150
|
+
projectRoot,
|
|
43151
|
+
files: options.files,
|
|
43152
|
+
aliases: options.aliases ?? { "@/": "src/" }
|
|
43153
|
+
});
|
|
43154
|
+
const files = options.files.map((path11) => ({
|
|
43155
|
+
path: path11,
|
|
43156
|
+
module: options.moduleOf?.(path11),
|
|
43157
|
+
symbols: options.symbolsOf?.(path11)
|
|
43158
|
+
}));
|
|
43159
|
+
return buildRepoMap(files, edges, { tokenBudget: options.tokenBudget });
|
|
43160
|
+
}
|
|
43161
|
+
|
|
43162
|
+
// src/context/existing-surface.ts
|
|
43163
|
+
init_contextual_blurb();
|
|
43164
|
+
var EXISTING_SURFACE_HEADING = "## Existing surface";
|
|
43165
|
+
var EXISTING_SURFACE_FRAMING = "> Before writing new helpers, check this surface \u2014 these already exist in this project.";
|
|
43166
|
+
function estimateTokens2(text) {
|
|
43167
|
+
return Math.ceil(text.length / 4);
|
|
43168
|
+
}
|
|
43169
|
+
function formatCardLine(card) {
|
|
43170
|
+
const head = card.signature?.trim() ? card.signature.trim() : card.name;
|
|
43171
|
+
const location = card.line ? `${card.file}:${card.line}` : card.file;
|
|
43172
|
+
const parts = [`- \`${head}\` \u2014 ${location}`];
|
|
43173
|
+
if (typeof card.callerCount === "number") {
|
|
43174
|
+
parts.push(`\xB7 called from ${card.callerCount} ${card.callerCount === 1 ? "place" : "places"}`);
|
|
43175
|
+
}
|
|
43176
|
+
if (card.module) {
|
|
43177
|
+
parts.push(`\xB7 ${card.module}`);
|
|
43178
|
+
}
|
|
43179
|
+
return parts.join(" ");
|
|
43180
|
+
}
|
|
43181
|
+
function headerFor(shown) {
|
|
43182
|
+
return `${EXISTING_SURFACE_HEADING} \u2014 ${shown} existing symbol${shown === 1 ? "" : "s"} for the files in play`;
|
|
43183
|
+
}
|
|
43184
|
+
function composeExistingSurfaceSection(cards, options = {}) {
|
|
43185
|
+
if (cards.length === 0) {
|
|
43186
|
+
return "";
|
|
43187
|
+
}
|
|
43188
|
+
const tokenBudget = options.tokenBudget ?? DEFAULT_EXISTING_SURFACE_TOKENS;
|
|
43189
|
+
let tokens = estimateTokens2(EXISTING_SURFACE_FRAMING) + estimateTokens2(headerFor(cards.length));
|
|
43190
|
+
const lines = [];
|
|
43191
|
+
let truncated = false;
|
|
43192
|
+
for (const card of cards) {
|
|
43193
|
+
const line = formatCardLine(card);
|
|
43194
|
+
const lineTokens = estimateTokens2(line) + 1;
|
|
43195
|
+
if (lines.length > 0 && tokens + lineTokens > tokenBudget) {
|
|
43196
|
+
truncated = true;
|
|
43197
|
+
break;
|
|
43198
|
+
}
|
|
43199
|
+
lines.push(line);
|
|
43200
|
+
tokens += lineTokens;
|
|
43201
|
+
}
|
|
43202
|
+
const remaining = cards.length - lines.length;
|
|
43203
|
+
const trailer = truncated && remaining > 0 ? `
|
|
43204
|
+
\u2026and ${remaining} more exported symbol${remaining === 1 ? "" : "s"} \u2014 run \`paqad-ai index query <name>\` to look one up.` : "";
|
|
43205
|
+
return `${headerFor(lines.length)}
|
|
43206
|
+
${EXISTING_SURFACE_FRAMING}
|
|
43207
|
+
|
|
43208
|
+
${lines.join("\n")}${trailer}
|
|
43209
|
+
`;
|
|
43210
|
+
}
|
|
43211
|
+
var SOURCE_EXT_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|php|dart)$/;
|
|
43212
|
+
function toPosix(path11) {
|
|
43213
|
+
return path11.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
43214
|
+
}
|
|
43215
|
+
function modulePrefix(path11) {
|
|
43216
|
+
return path11.split("/").slice(0, 2).join("/");
|
|
43217
|
+
}
|
|
43218
|
+
function basenameNoExt(path11) {
|
|
43219
|
+
const base = path11.slice(path11.lastIndexOf("/") + 1);
|
|
43220
|
+
const dot = base.lastIndexOf(".");
|
|
43221
|
+
return dot <= 0 ? base : base.slice(0, dot);
|
|
43222
|
+
}
|
|
43223
|
+
function selectCandidateFiles(allFiles, workingSet, query, index) {
|
|
43224
|
+
const working = new Set(workingSet);
|
|
43225
|
+
const workingModules = new Set([...working].map(modulePrefix));
|
|
43226
|
+
if (working.size === 0 && query.trim().length === 0) {
|
|
43227
|
+
return [];
|
|
43228
|
+
}
|
|
43229
|
+
const queryLower = query.toLowerCase();
|
|
43230
|
+
const wanted = /* @__PURE__ */ new Set();
|
|
43231
|
+
for (const file of allFiles) {
|
|
43232
|
+
if (working.has(file) || workingModules.size > 0 && workingModules.has(modulePrefix(file))) {
|
|
43233
|
+
wanted.add(file);
|
|
43234
|
+
continue;
|
|
43235
|
+
}
|
|
43236
|
+
const base = basenameNoExt(file).toLowerCase();
|
|
43237
|
+
if (base.length >= 4 && queryLower.includes(base)) {
|
|
43238
|
+
wanted.add(file);
|
|
43239
|
+
}
|
|
43240
|
+
}
|
|
43241
|
+
if (index && queryLower.length > 0) {
|
|
43242
|
+
for (const symbol of index.symbols) {
|
|
43243
|
+
if (symbol.name.length >= 5 && queryLower.includes(symbol.name.toLowerCase())) {
|
|
43244
|
+
wanted.add(symbol.file);
|
|
43245
|
+
}
|
|
43246
|
+
}
|
|
43247
|
+
}
|
|
43248
|
+
const universe = new Set(allFiles);
|
|
43249
|
+
return [...wanted].filter((file) => universe.has(file));
|
|
43250
|
+
}
|
|
43251
|
+
async function gatherExistingSurface(projectRoot, options = {}) {
|
|
43252
|
+
try {
|
|
43253
|
+
const tokenBudget = options.tokenBudget ?? DEFAULT_EXISTING_SURFACE_TOKENS;
|
|
43254
|
+
const query = options.query ?? "";
|
|
43255
|
+
const index = readCodeKnowledgeIndex(projectRoot);
|
|
43256
|
+
const workingSet = (options.changedPaths ?? []).map(toPosix).filter((path11) => SOURCE_EXT_RE.test(path11));
|
|
43257
|
+
const allFiles = index ? index.files.map((file) => file.path) : scanWorkingTree(projectRoot, SOURCE_GLOBS).map(toPosix);
|
|
43258
|
+
const candidates = selectCandidateFiles(allFiles, workingSet, query, index);
|
|
43259
|
+
if (candidates.length === 0) {
|
|
43260
|
+
return "";
|
|
43261
|
+
}
|
|
43262
|
+
const symbolsByFile = /* @__PURE__ */ new Map();
|
|
43263
|
+
if (index) {
|
|
43264
|
+
for (const symbol of index.symbols) {
|
|
43265
|
+
const list = symbolsByFile.get(symbol.file) ?? [];
|
|
43266
|
+
list.push(symbol);
|
|
43267
|
+
symbolsByFile.set(symbol.file, list);
|
|
43268
|
+
}
|
|
43269
|
+
}
|
|
43270
|
+
const moduleResolver = buildModuleRoleResolver(projectRoot);
|
|
43271
|
+
const repoMap = await buildProjectRepoMap(projectRoot, {
|
|
43272
|
+
files: candidates,
|
|
43273
|
+
moduleOf: (path11) => moduleResolver(path11),
|
|
43274
|
+
symbolsOf: index ? (path11) => (symbolsByFile.get(path11) ?? []).map((symbol) => symbol.name) : (path11) => extractNames(projectRoot, path11)
|
|
43275
|
+
});
|
|
43276
|
+
const cards = [];
|
|
43277
|
+
for (const entry of repoMap.entries) {
|
|
43278
|
+
if (index) {
|
|
43279
|
+
const symbols = (symbolsByFile.get(entry.path) ?? []).slice().sort((a, b) => b.caller_count - a.caller_count || a.name.localeCompare(b.name));
|
|
43280
|
+
for (const symbol of symbols) {
|
|
43281
|
+
cards.push({
|
|
43282
|
+
name: symbol.name,
|
|
43283
|
+
signature: symbol.signature,
|
|
43284
|
+
file: symbol.file,
|
|
43285
|
+
line: symbol.line,
|
|
43286
|
+
callerCount: symbol.caller_count,
|
|
43287
|
+
module: symbol.module_slug ?? entry.module ?? void 0
|
|
43288
|
+
});
|
|
43289
|
+
}
|
|
43290
|
+
} else {
|
|
43291
|
+
for (const name of entry.symbols) {
|
|
43292
|
+
cards.push({ name, file: entry.path, module: entry.module });
|
|
43293
|
+
}
|
|
43294
|
+
}
|
|
43295
|
+
}
|
|
43296
|
+
return composeExistingSurfaceSection(cards, { tokenBudget });
|
|
43297
|
+
} catch {
|
|
43298
|
+
return "";
|
|
43299
|
+
}
|
|
43300
|
+
}
|
|
43301
|
+
function extractNames(projectRoot, relPath) {
|
|
43302
|
+
try {
|
|
43303
|
+
const content = readFileSync101(join204(projectRoot, relPath), "utf8");
|
|
43304
|
+
return extractSymbols(relPath, content).map((symbol) => symbol.name);
|
|
43305
|
+
} catch {
|
|
43306
|
+
return [];
|
|
43307
|
+
}
|
|
43308
|
+
}
|
|
43309
|
+
|
|
42999
43310
|
// src/context/retrieval-context.ts
|
|
43000
43311
|
init_esm_shims();
|
|
43001
43312
|
init_project_intelligence();
|
|
@@ -43165,11 +43476,11 @@ async function gatherWorkingSetSlices(projectRoot, options = {}) {
|
|
|
43165
43476
|
// src/pipeline/session-route.ts
|
|
43166
43477
|
init_esm_shims();
|
|
43167
43478
|
init_paths();
|
|
43168
|
-
import { mkdirSync as mkdirSync51, readFileSync as
|
|
43169
|
-
import { dirname as dirname86, join as
|
|
43479
|
+
import { mkdirSync as mkdirSync51, readFileSync as readFileSync102, writeFileSync as writeFileSync43 } from "fs";
|
|
43480
|
+
import { dirname as dirname86, join as join205 } from "path";
|
|
43170
43481
|
var SESSION_ROUTE_FILE = ".session-route.json";
|
|
43171
43482
|
function sessionRouteDir(projectRoot) {
|
|
43172
|
-
return
|
|
43483
|
+
return join205(projectRoot, dirname86(PATHS.CONTEXT_SESSION_ARTIFACT));
|
|
43173
43484
|
}
|
|
43174
43485
|
var VALID_WORKFLOWS2 = new Set(ROUTED_WORKFLOWS);
|
|
43175
43486
|
function compositionForRoute(route) {
|
|
@@ -43184,7 +43495,7 @@ function compositionForRoute(route) {
|
|
|
43184
43495
|
function readSessionRoute(projectRoot) {
|
|
43185
43496
|
try {
|
|
43186
43497
|
const parsed = JSON.parse(
|
|
43187
|
-
|
|
43498
|
+
readFileSync102(join205(sessionRouteDir(projectRoot), SESSION_ROUTE_FILE), "utf8")
|
|
43188
43499
|
);
|
|
43189
43500
|
if (typeof parsed.workflow !== "string" || !VALID_WORKFLOWS2.has(parsed.workflow)) {
|
|
43190
43501
|
return null;
|
|
@@ -43203,12 +43514,12 @@ init_recorder();
|
|
|
43203
43514
|
|
|
43204
43515
|
// src/rag/background-sync.ts
|
|
43205
43516
|
init_esm_shims();
|
|
43206
|
-
import { join as
|
|
43517
|
+
import { join as join206 } from "path";
|
|
43207
43518
|
init_paths();
|
|
43208
43519
|
init_service();
|
|
43209
43520
|
var STALE_LOCK_MS2 = 10 * 60 * 1e3;
|
|
43210
43521
|
async function backgroundIndexSync(projectRoot, providerFactory) {
|
|
43211
|
-
const lockDir =
|
|
43522
|
+
const lockDir = join206(projectRoot, PATHS.LOCKS_DIR, "rag-sync.lock");
|
|
43212
43523
|
const lock = tryAcquireLock(lockDir, { staleLockMs: STALE_LOCK_MS2 });
|
|
43213
43524
|
if (!lock.acquired) {
|
|
43214
43525
|
return { synced: false, reason: "in-flight" };
|
|
@@ -43235,8 +43546,8 @@ async function backgroundIndexSync(projectRoot, providerFactory) {
|
|
|
43235
43546
|
init_esm_shims();
|
|
43236
43547
|
init_atomic_artifact();
|
|
43237
43548
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
43238
|
-
import { readFileSync as
|
|
43239
|
-
import { join as
|
|
43549
|
+
import { readFileSync as readFileSync103 } from "fs";
|
|
43550
|
+
import { join as join207 } from "path";
|
|
43240
43551
|
|
|
43241
43552
|
// src/background/debounce-marker.ts
|
|
43242
43553
|
init_esm_shims();
|
|
@@ -43312,11 +43623,11 @@ function computeBaseDrift(projectRoot, options = {}) {
|
|
|
43312
43623
|
async function refreshBaseDrift(projectRoot, options = {}) {
|
|
43313
43624
|
const now = options.now ?? Date.now;
|
|
43314
43625
|
const minIntervalMs = options.minIntervalMs ?? DEFAULT_BASE_DRIFT_INTERVAL_MS;
|
|
43315
|
-
const markerPath =
|
|
43626
|
+
const markerPath = join207(projectRoot, PATHS.BASE_DRIFT_MARKER);
|
|
43316
43627
|
if (shouldDebounce(markerPath, minIntervalMs, now)) {
|
|
43317
43628
|
return { refreshed: false, reason: "debounced" };
|
|
43318
43629
|
}
|
|
43319
|
-
const lockDir =
|
|
43630
|
+
const lockDir = join207(projectRoot, PATHS.BASE_DRIFT_LOCK);
|
|
43320
43631
|
const lock = tryAcquireLock(lockDir, { staleLockMs: STALE_LOCK_MS3 });
|
|
43321
43632
|
if (!lock.acquired) {
|
|
43322
43633
|
return { refreshed: false, reason: "in-flight" };
|
|
@@ -43340,7 +43651,7 @@ async function refreshBaseDrift(projectRoot, options = {}) {
|
|
|
43340
43651
|
const snapshot = computeBaseDrift(projectRoot, options);
|
|
43341
43652
|
if (snapshot) {
|
|
43342
43653
|
await atomicWriteFile(
|
|
43343
|
-
|
|
43654
|
+
join207(projectRoot, PATHS.BASE_DRIFT_STATE),
|
|
43344
43655
|
`${JSON.stringify(snapshot, null, 2)}
|
|
43345
43656
|
`
|
|
43346
43657
|
);
|
|
@@ -43355,7 +43666,7 @@ async function refreshBaseDrift(projectRoot, options = {}) {
|
|
|
43355
43666
|
function loadBaseDrift(projectRoot) {
|
|
43356
43667
|
try {
|
|
43357
43668
|
const parsed = JSON.parse(
|
|
43358
|
-
|
|
43669
|
+
readFileSync103(join207(projectRoot, PATHS.BASE_DRIFT_STATE), "utf8")
|
|
43359
43670
|
);
|
|
43360
43671
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.base_branch === "string" && typeof parsed.ahead === "number") {
|
|
43361
43672
|
return parsed;
|
|
@@ -43853,9 +44164,18 @@ function createRagCommand() {
|
|
|
43853
44164
|
}
|
|
43854
44165
|
const route = readSessionRoute(options.projectRoot);
|
|
43855
44166
|
const { loadRules, retrieves } = compositionForRoute(route);
|
|
43856
|
-
const
|
|
44167
|
+
const intelligence = resolveFrameworkConfig(options.projectRoot).intelligence;
|
|
44168
|
+
const existingSurfaceSection = loadRules ? await gatherExistingSurface(options.projectRoot, {
|
|
44169
|
+
changedPaths: (await loadChangeEvidence(options.projectRoot)).files,
|
|
44170
|
+
query: route?.query,
|
|
44171
|
+
tokenBudget: intelligence.existing_surface_tokens
|
|
44172
|
+
}) : "";
|
|
44173
|
+
const ragEnabled = intelligence.rag_enabled;
|
|
43857
44174
|
if (!ragEnabled) {
|
|
43858
|
-
const target2 = await refreshRuleContext(options.projectRoot, {
|
|
44175
|
+
const target2 = await refreshRuleContext(options.projectRoot, {
|
|
44176
|
+
existingSurfaceSection,
|
|
44177
|
+
loadRules
|
|
44178
|
+
});
|
|
43859
44179
|
if (!options.quiet) {
|
|
43860
44180
|
process.stdout.write(
|
|
43861
44181
|
`${target2 ? `wrote ${target2}` : "nothing to compose"}; rule-only (rag off)
|
|
@@ -43873,8 +44193,8 @@ function createRagCommand() {
|
|
|
43873
44193
|
const packEntries = usesContextPack ? distillSlices(slices, {
|
|
43874
44194
|
readFile: (path11) => {
|
|
43875
44195
|
try {
|
|
43876
|
-
return
|
|
43877
|
-
isAbsolute11(path11) ? path11 :
|
|
44196
|
+
return readFileSync104(
|
|
44197
|
+
isAbsolute11(path11) ? path11 : join208(options.projectRoot, path11),
|
|
43878
44198
|
"utf8"
|
|
43879
44199
|
);
|
|
43880
44200
|
} catch {
|
|
@@ -43890,6 +44210,7 @@ function createRagCommand() {
|
|
|
43890
44210
|
driftSection = composeBaseDriftSection(loadBaseDrift(options.projectRoot));
|
|
43891
44211
|
}
|
|
43892
44212
|
const target = await refreshRuleContext(options.projectRoot, {
|
|
44213
|
+
existingSurfaceSection,
|
|
43893
44214
|
memorySection,
|
|
43894
44215
|
retrievalSection,
|
|
43895
44216
|
driftSection,
|
|
@@ -43995,7 +44316,7 @@ function createRagCommand() {
|
|
|
43995
44316
|
}
|
|
43996
44317
|
if (options.baseline) {
|
|
43997
44318
|
const baselineSnapshot = JSON.parse(
|
|
43998
|
-
|
|
44319
|
+
readFileSync104(options.baseline, "utf8")
|
|
43999
44320
|
);
|
|
44000
44321
|
comparison = compareConfigurations(baselineSnapshot, candidateSnapshot, mode);
|
|
44001
44322
|
}
|
|
@@ -44177,8 +44498,8 @@ function createRagEvidenceCommand() {
|
|
|
44177
44498
|
// src/cli/commands/refresh.ts
|
|
44178
44499
|
init_esm_shims();
|
|
44179
44500
|
import { Command as Command30 } from "commander";
|
|
44180
|
-
import { existsSync as existsSync108, readFileSync as
|
|
44181
|
-
import { join as
|
|
44501
|
+
import { existsSync as existsSync108, readFileSync as readFileSync105, writeFileSync as writeFileSync45 } from "fs";
|
|
44502
|
+
import { join as join209 } from "path";
|
|
44182
44503
|
init_paths();
|
|
44183
44504
|
init_project_profile2();
|
|
44184
44505
|
init_service();
|
|
@@ -44308,7 +44629,7 @@ async function refreshProviderEntries(projectRoot) {
|
|
|
44308
44629
|
removeObsoleteContractDocs(projectRoot);
|
|
44309
44630
|
for (const type of ADAPTER_TYPES) {
|
|
44310
44631
|
const adapter = AdapterFactory.create(type);
|
|
44311
|
-
const configPath =
|
|
44632
|
+
const configPath = join209(projectRoot, adapter.getConfigPath());
|
|
44312
44633
|
if (!existsSync108(configPath)) {
|
|
44313
44634
|
continue;
|
|
44314
44635
|
}
|
|
@@ -44321,14 +44642,14 @@ async function refreshProviderEntries(projectRoot) {
|
|
|
44321
44642
|
}
|
|
44322
44643
|
}
|
|
44323
44644
|
function writeRefreshDrift(projectRoot, refreshDrift) {
|
|
44324
|
-
const path11 =
|
|
44645
|
+
const path11 = join209(projectRoot, PATHS.STACK_DRIFT);
|
|
44325
44646
|
const current = readExistingJson(path11);
|
|
44326
44647
|
writeFileSync45(path11, `${JSON.stringify({ ...current ?? {}, ...refreshDrift }, null, 2)}
|
|
44327
44648
|
`);
|
|
44328
44649
|
}
|
|
44329
44650
|
function readExistingJson(path11) {
|
|
44330
44651
|
try {
|
|
44331
|
-
return JSON.parse(
|
|
44652
|
+
return JSON.parse(readFileSync105(path11, "utf8"));
|
|
44332
44653
|
} catch {
|
|
44333
44654
|
return null;
|
|
44334
44655
|
}
|
|
@@ -44337,12 +44658,12 @@ function resolveChangedFiles(projectRoot, contextChangedFiles) {
|
|
|
44337
44658
|
if (contextChangedFiles.length > 0) {
|
|
44338
44659
|
return [...new Set(contextChangedFiles)].sort();
|
|
44339
44660
|
}
|
|
44340
|
-
const trackedPath =
|
|
44661
|
+
const trackedPath = join209(projectRoot, PATHS.CHANGED_FILES);
|
|
44341
44662
|
if (!existsSync108(trackedPath)) {
|
|
44342
44663
|
return [];
|
|
44343
44664
|
}
|
|
44344
44665
|
try {
|
|
44345
|
-
const parsed = JSON.parse(
|
|
44666
|
+
const parsed = JSON.parse(readFileSync105(trackedPath, "utf8"));
|
|
44346
44667
|
if (!Array.isArray(parsed)) {
|
|
44347
44668
|
return [];
|
|
44348
44669
|
}
|
|
@@ -44410,7 +44731,7 @@ function createRulesCommand() {
|
|
|
44410
44731
|
|
|
44411
44732
|
// src/cli/commands/spec.ts
|
|
44412
44733
|
init_esm_shims();
|
|
44413
|
-
import { readFileSync as
|
|
44734
|
+
import { readFileSync as readFileSync106 } from "fs";
|
|
44414
44735
|
import { basename as basename16 } from "path";
|
|
44415
44736
|
import { Command as Command33 } from "commander";
|
|
44416
44737
|
|
|
@@ -44555,7 +44876,7 @@ function createSpecCommand() {
|
|
|
44555
44876
|
(specFile, options) => {
|
|
44556
44877
|
let markdown;
|
|
44557
44878
|
try {
|
|
44558
|
-
markdown =
|
|
44879
|
+
markdown = readFileSync106(specFile, "utf8");
|
|
44559
44880
|
} catch {
|
|
44560
44881
|
console.error(`could not read spec file "${specFile}"`);
|
|
44561
44882
|
process.exitCode = 1;
|