amsd-pipeline-workflow 0.1.8 → 0.1.10

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.
@@ -384,10 +384,14 @@ async function reproStep(prep) {
384
384
  if (!source) return { committed: false, reason: 'no testable source file in the change' }
385
385
  const cand = prep.candidates[source]
386
386
  const fb = { typecheck: '', assertions: '', commit_rejected: '' }
387
+ // the answer names the source the workflow chose, and only that (B61: unexplained, the model named the codeline, then the test)
388
+ const schema = { ...SCHEMAS.repro, properties: { ...SCHEMAS.repro.properties,
389
+ source: { type: 'string', enum: [source], description: 'the source file your test covers: exactly this path' },
390
+ test: { type: 'string', description: \`the path of the test file you wrote, relative to the codeline root (planned: \${cand.target})\` } } }
387
391
  for (let i = 0; i < PLAN.repro.maxAttempts; i++) {
388
392
  const model = PLAN.repro.ladder[Math.min(i, PLAN.repro.ladder.length - 1)]
389
393
  const a = await agentCall(relativize(cand.prompt) + fb.typecheck + fb.assertions + fb.commit_rejected,
390
- { agentType: PLAN.agents.reproWriter, model, schema: SCHEMAS.repro, label: \`repro test #\${i + 1}\`, phase: 'Writer' })
394
+ { agentType: PLAN.agents.reproWriter, model, schema, label: \`repro test #\${i + 1}\`, phase: 'Writer' })
391
395
  const v = (a && a.validation) || { valid: false, committed: false, class: 'no_file', feedback: '', reason: a ? 'the answer carries no validation' : 'the agent ended without an answer' }
392
396
  if (v.valid) return { committed: !!v.committed, attempts: i + 1, test: a.test, reason: v.reason }
393
397
  const slot = v.class === 'unchanged' ? 'commit_rejected' : v.class
@@ -20,7 +20,10 @@ function args(argv) { const a = {}; for (let i = 0; i < argv.length; i += 2) a[a
20
20
  function judge(a, input) {
21
21
  const pj = JSON.parse(fs.readFileSync(a.pipeline, 'utf8'));
22
22
  const prep = JSON.parse(fs.readFileSync(path.join(a.state, 'repro-prep.json'), 'utf8'));
23
- const source = String(input.source || ''); const test = String(input.test || '');
23
+ const source = String(input.source || '');
24
+ // a test named by its absolute path inside the codeline is that codeline-relative path (B61); anything else stays as named
25
+ const named = String(input.test || ''); const rel = path.isAbsolute(named) ? path.relative(pj.codeline, named) : named;
26
+ const test = rel && !rel.startsWith('..') && !path.isAbsolute(rel) ? rel : named;
24
27
  const cand = (prep.candidates || {})[source];
25
28
  if (!cand) return { valid: false, committed: false, class: 'no_file', feedback: '', reason: `'${source}' is not a source this change offered for a test` };
26
29
  const allowed = new Set([cand.target]);
@@ -686,7 +686,12 @@ if (require.main === module) {
686
686
  const answer = input.tool_input || {};
687
687
  const pj = JSON.parse(fs.readFileSync(a.pipeline, 'utf8'));
688
688
  const env = JSON.parse(fs.readFileSync(pj.env, 'utf8'));
689
- const out = (result) => process.stdout.write(`${JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow',
689
+ // THE HOOK'S STDOUT IS ITS JSON ONLY (B60, LIVE-AMSD-2974-10): the pipeline's Spec code runs in this process and logs with
690
+ // console.log (spec-mode-runner.js "… file(s) left its scope"); one such line ahead of the JSON and Claude Code drops the
691
+ // result. Everything else written to stdout goes to stderr; only `out` writes stdout.
692
+ const stdout = process.stdout.write.bind(process.stdout);
693
+ process.stdout.write = (chunk, ...rest) => process.stderr.write(chunk, ...rest);
694
+ const out = (result) => stdout(`${JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow',
690
695
  updatedInput: { ...answer, result } } })}\n`);
691
696
  Promise.resolve().then(() => sr.withEnv(env, () => handle(event, a, answer, pj)))
692
697
  .then((r) => out(r))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amsd-pipeline-workflow",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "The AMSD pipeline as Claude workflows. Installed by the amsd-pipeline installer: install.sh --workflows",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {