amsd-pipeline-shared 0.5.36 → 0.5.37

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.
@@ -124,16 +124,24 @@ function seed({ install, project, ticket, runsRoots }) {
124
124
  */
125
125
  // maxRebuild: how many generated prompts without an entry the launch accepts rebuilding (operator, 2026-10-19: a short,
126
126
  // NAMED list is acceptable). The launch states it (--max-rebuild); unstated it is 0 — every prompt must be reusable.
127
- function cache({ install, project, codeline, variant = process.env.EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild = 0 }) {
127
+ /** THE PROJECT THE LEG WILL USE (2026-10-24, run 13's resume refused on the install's older sets): a run that has its own project copy
128
+ * (the driver writes it once, at its first leg) works in it; a run not yet started works from the install's project. */
129
+ function launchProject({ install, project, runDir }) {
130
+ const own = runDir ? path.join(runDir, 'project') : '';
131
+ return own && fs.existsSync(own) ? own : path.join(orchOf(install), 'projects', project);
132
+ }
133
+
134
+ function cache({ install, project, projectConfigDir, codeline, variant = process.env.EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild = 0 }) {
128
135
  const O = orchOf(install);
129
- const C = path.join(O, 'projects', project, '.prompt-cache', codeline);
136
+ const PCD = projectConfigDir || path.join(O, 'projects', project);
137
+ const C = path.join(PCD, '.prompt-cache', codeline);
130
138
  const b = require(path.join(scriptsOf(install), 'lib', 'project-prompt-builder.js'));
131
139
  const tpl = (t) => path.join(O, 'prompts', 'templates', `${t}.json`);
132
140
  // A COMPLETE SET IS REUSED WHOLE (2026-10-22): the mint step keeps a codeline whose set is complete ("completed its agents and
133
141
  // prompts — kept") and no prompt is built, so per-prompt entries are not needed — the builder's own test, as the mint step's
134
142
  const prev = process.env.EPAM_BROWNFIELD; process.env.EPAM_BROWNFIELD = variant === 'brownfield' ? '1' : '';
135
143
  let whole;
136
- try { whole = b.codelineSetComplete({ projectConfigDir: path.join(O, 'projects', project), codeline, templatesDir: path.join(O, 'prompts', 'templates'), registryFile: path.join(O, 'agents', 'invocation-profiles.json') }); }
144
+ try { whole = b.codelineSetComplete({ projectConfigDir: PCD, codeline, templatesDir: path.join(O, 'prompts', 'templates'), registryFile: path.join(O, 'agents', 'invocation-profiles.json') }); }
137
145
  finally { if (prev === undefined) delete process.env.EPAM_BROWNFIELD; else process.env.EPAM_BROWNFIELD = prev; }
138
146
  if (whole && whole.complete) return res('cache', true, `${codeline}: its complete set is reused whole by the mint step — nothing rebuilt`, { required: 0, missing: [], willRebuild: [] });
139
147
  const problems = [];
@@ -141,7 +149,7 @@ function cache({ install, project, codeline, variant = process.env.EPAM_BROWNFIE
141
149
  if (!prompts.length) problems.push(`no cached prompt set (${path.join(C, 'prompts')})`);
142
150
  const minted = b.MINTED_FILES.filter((f) => !fs.existsSync(path.join(C, 'minted', f)));
143
151
  if (minted.length) problems.push(`minted files missing: ${minted.join(', ')}`);
144
- const marker = path.join(O, 'projects', project, '.prompt-cache', `.complete-${codeline}${variant ? `.${variant}` : ''}`);
152
+ const marker = path.join(PCD, '.prompt-cache', `.complete-${codeline}${variant ? `.${variant}` : ''}`);
145
153
  if (!fs.existsSync(marker)) problems.push(`no completion marker ${path.basename(marker)}`);
146
154
  const list = b.provisioningList({ bootstrap: readJson(path.join(O, 'prompts', 'bootstrap.json'), {}), registry: readJson(path.join(O, 'agents', 'invocation-profiles.json'), {}), templateExists: (t) => fs.existsSync(tpl(t)), templatesDir: path.join(O, 'prompts', 'templates') });
147
155
  const multi = (t) => Object.prototype.hasOwnProperty.call(readJson(tpl(t), {}), 'bodies');
@@ -159,12 +167,12 @@ function cache({ install, project, codeline, variant = process.env.EPAM_BROWNFIE
159
167
  * perfect"): each codeline folder's recorded agents and prompts, and its completion built from the current inputs
160
168
  * (project-prompt-builder.js codelineSetComplete). A lane whose codeline has none does not run, so the launch is not started.
161
169
  */
162
- function codelineSets({ install, project, codelines = [], env = {} }) {
170
+ function codelineSets({ install, project, projectConfigDir, codelines = [], env = {} }) {
163
171
  const O = orchOf(install);
164
172
  const b = require(path.join(scriptsOf(install), 'lib', 'project-prompt-builder.js'));
165
173
  const prev = process.env.EPAM_BROWNFIELD; process.env.EPAM_BROWNFIELD = env.EPAM_BROWNFIELD === '1' ? '1' : '';
166
174
  try {
167
- const rows = codelines.map((codeline) => ({ codeline, ...b.codelineSetComplete({ projectConfigDir: path.join(O, 'projects', project), codeline,
175
+ const rows = codelines.map((codeline) => ({ codeline, ...b.codelineSetComplete({ projectConfigDir: projectConfigDir || path.join(O, 'projects', project), codeline,
168
176
  templatesDir: path.join(O, 'prompts', 'templates'), registryFile: path.join(O, 'agents', 'invocation-profiles.json') }) }));
169
177
  const bad = rows.filter((r) => !r.complete);
170
178
  if (!codelines.length) return res('codeline-sets', false, 'no codeline named — the sets every lane works from cannot be checked');
@@ -322,8 +330,9 @@ function prelaunch(o) {
322
330
  results.push(langfuse({ install: o.install, env: o.env, runId: o.runId, outDir: o.outDir }));
323
331
  if (o.ticket) results.push(seed({ install: o.install, project: o.project, ticket: o.ticket, runsRoots: o.runsRoots || [] }));
324
332
  // the variant (brownfield) is the run's, from the env the launch hands over — not this process's own environment
325
- if (o.codeline) results.push(cache({ install: o.install, project: o.project, codeline: o.codeline, variant: (o.env || {}).EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild: o.maxRebuild || 0 }));
326
- if (Array.isArray(o.codelines)) results.push(codelineSets({ install: o.install, project: o.project, codelines: o.codelines, env: o.env || {} }));
333
+ const pcd = launchProject(o);
334
+ if (o.codeline) results.push(cache({ install: o.install, project: o.project, projectConfigDir: pcd, codeline: o.codeline, variant: (o.env || {}).EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild: o.maxRebuild || 0 }));
335
+ if (Array.isArray(o.codelines)) results.push(codelineSets({ install: o.install, project: o.project, projectConfigDir: pcd, codelines: o.codelines, env: o.env || {} }));
327
336
  if (o.copy) results.push(permissions({ install: o.install, project: o.project, runDir: o.runDir, copy: o.copy }));
328
337
  results.push(cost({ install: o.install, set: o.set || o.env.EPAM_PROVIDER_SET || 'claude', tmpDir: o.outDir }));
329
338
  results.push(alone({ install: o.install }));
@@ -337,7 +346,7 @@ function prelaunch(o) {
337
346
  return report;
338
347
  }
339
348
 
340
- module.exports = { prelaunch, prelaunchCli, preflight, langfuse, langfuseEnv, seed, cache, codelineSets, permissions, cost, ladderModels, alone, memory, noTimeout, checklist, ancestors };
349
+ module.exports = { prelaunch, prelaunchCli, preflight, langfuse, langfuseEnv, seed, cache, codelineSets, launchProject, permissions, cost, ladderModels, alone, memory, noTimeout, checklist, ancestors };
341
350
 
342
351
  /**
343
352
  * THE COMMAND, for every pipeline:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amsd-pipeline-shared",
3
- "version": "0.5.36",
3
+ "version": "0.5.37",
4
4
  "description": "The AMSD pipeline's shared components, one source for the bash pipeline and its Claude workflows: the model-call gateway (llm-handler.sh — retry, ladder, self-heal, cost) and the libraries it runs.",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {