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 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) return null;
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.59.0";
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 readFileSync103 } from "fs";
42663
- import { isAbsolute as isAbsolute11, join as join207 } from "path";
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 readFileSync101, writeFileSync as writeFileSync43 } from "fs";
43169
- import { dirname as dirname86, join as join204 } from "path";
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 join204(projectRoot, dirname86(PATHS.CONTEXT_SESSION_ARTIFACT));
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
- readFileSync101(join204(sessionRouteDir(projectRoot), SESSION_ROUTE_FILE), "utf8")
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 join205 } from "path";
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 = join205(projectRoot, PATHS.LOCKS_DIR, "rag-sync.lock");
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 readFileSync102 } from "fs";
43239
- import { join as join206 } from "path";
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 = join206(projectRoot, PATHS.BASE_DRIFT_MARKER);
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 = join206(projectRoot, PATHS.BASE_DRIFT_LOCK);
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
- join206(projectRoot, PATHS.BASE_DRIFT_STATE),
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
- readFileSync102(join206(projectRoot, PATHS.BASE_DRIFT_STATE), "utf8")
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 ragEnabled = resolveFrameworkConfig(options.projectRoot).intelligence.rag_enabled;
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, { loadRules });
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 readFileSync103(
43877
- isAbsolute11(path11) ? path11 : join207(options.projectRoot, 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
- readFileSync103(options.baseline, "utf8")
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 readFileSync104, writeFileSync as writeFileSync45 } from "fs";
44181
- import { join as join208 } from "path";
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 = join208(projectRoot, adapter.getConfigPath());
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 = join208(projectRoot, PATHS.STACK_DRIFT);
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(readFileSync104(path11, "utf8"));
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 = join208(projectRoot, PATHS.CHANGED_FILES);
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(readFileSync104(trackedPath, "utf8"));
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 readFileSync105 } from "fs";
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 = readFileSync105(specFile, "utf8");
44879
+ markdown = readFileSync106(specFile, "utf8");
44559
44880
  } catch {
44560
44881
  console.error(`could not read spec file "${specFile}"`);
44561
44882
  process.exitCode = 1;