svharness 0.15.11 → 0.15.13

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.
Files changed (43) hide show
  1. package/README.md +106 -2
  2. package/auto/auto-harness-detail-design.md +136 -4
  3. package/auto/skills/svharness/SKILL.md +44 -1
  4. package/auto/templates/auto-pack-req.config.example.yaml +29 -0
  5. package/auto/templates/auto.config.example.yaml +1 -1
  6. package/auto/templates/phase-prompts/S40-adversarial-review.md +31 -0
  7. package/auto/templates/phase-prompts/S40-review.md +22 -0
  8. package/auto/templates/phase-prompts/S40-sample-trace.md +26 -0
  9. package/auto/templates/requirements-review-rubric.yaml +79 -0
  10. package/dist/commands/auto-pack-req.js +70 -0
  11. package/dist/commands/auto.js +16 -1
  12. package/dist/commands/convert.js +2 -0
  13. package/dist/commands/shell-integration.js +29 -56
  14. package/dist/config/merge-options.js +2 -0
  15. package/dist/config/normalize.js +7 -0
  16. package/dist/constants/convert.js +5 -0
  17. package/dist/core/markitdown-client.js +7 -2
  18. package/dist/index.js +77 -5
  19. package/dist/lib/acp-agent-cli-resolver.js +193 -0
  20. package/dist/lib/acp-client.js +4 -2
  21. package/dist/lib/agent-launcher.js +9 -4
  22. package/dist/lib/auto-assets.js +1 -0
  23. package/dist/lib/auto-optimize.js +23 -3
  24. package/dist/lib/auto-orchestrator.js +53 -20
  25. package/dist/lib/auto-pack-req-context.js +88 -0
  26. package/dist/lib/auto-pack-req-finalize.js +28 -0
  27. package/dist/lib/auto-req-pack-review.js +161 -0
  28. package/dist/lib/auto-sample-trace.js +144 -0
  29. package/dist/lib/auto-state.js +124 -15
  30. package/dist/lib/gate-checker.js +20 -10
  31. package/dist/lib/phase-runner.js +13 -2
  32. package/dist/lib/ps-codechat-alias.js +29 -16
  33. package/dist/lib/review-parser.js +14 -0
  34. package/dist/lib/score-aggregator.js +21 -0
  35. package/dist/lib/win-registry.js +1 -1
  36. package/dist/utils/validate-args.js +2 -1
  37. package/package.json +3 -2
  38. package/templates/codechat/Start-CodeChat.ps1 +176 -135
  39. package/templates/codechat/bash.exe.stackdump +29 -0
  40. package/templates/codechat/docs/project-structure.md +59 -0
  41. package/templates/svharness.config.example.yaml +2 -0
  42. package/dist/lib/launch-script-path.js +0 -24
  43. package/templates/codechat/.claude/.env +0 -59
@@ -4,6 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.dedupePhases = dedupePhases;
7
+ exports.dedupePhaseFields = dedupePhaseFields;
8
+ exports.repairBuildStateYaml = repairBuildStateYaml;
9
+ exports.quoteUnsafeNextAction = quoteUnsafeNextAction;
7
10
  exports.readBuildState = readBuildState;
8
11
  exports.writeBuildState = writeBuildState;
9
12
  exports.phaseStatus = phaseStatus;
@@ -60,29 +63,135 @@ function dedupePhases(rawYaml) {
60
63
  }
61
64
  return result.join('\n');
62
65
  }
66
+ const PHASE_FIELD_REGEX = /^ ([A-Za-z_][\w-]*):/;
67
+ /**
68
+ * Within each phase block, drop duplicate field keys (e.g. a second
69
+ * `completed_at:` appended by ACP text-editing). Keeps the **last**
70
+ * occurrence so the most recent agent edit wins.
71
+ */
72
+ function dedupeFieldsInPhaseBlock(blockLines) {
73
+ if (blockLines.length === 0)
74
+ return blockLines;
75
+ const spans = [];
76
+ for (let i = 0; i < blockLines.length; i++) {
77
+ const match = blockLines[i].match(PHASE_FIELD_REGEX);
78
+ if (!match)
79
+ continue;
80
+ if (spans.length > 0)
81
+ spans[spans.length - 1].end = i;
82
+ spans.push({ key: match[1], start: i, end: blockLines.length });
83
+ }
84
+ const lastByKey = new Map();
85
+ spans.forEach((span, idx) => lastByKey.set(span.key, idx));
86
+ const out = [];
87
+ spans.forEach((span, idx) => {
88
+ if (lastByKey.get(span.key) === idx) {
89
+ out.push(...blockLines.slice(span.start, span.end));
90
+ }
91
+ });
92
+ return out;
93
+ }
94
+ /**
95
+ * Strip duplicate field keys inside each phase block under `phases:`.
96
+ */
97
+ function dedupePhaseFields(rawYaml) {
98
+ const lines = rawYaml.split('\n');
99
+ const phaseKeyRegex = /^ (\S+):$/;
100
+ const result = [];
101
+ let inPhases = false;
102
+ let phaseHeader = null;
103
+ let blockLines = [];
104
+ const flushPhase = () => {
105
+ if (phaseHeader === null)
106
+ return;
107
+ result.push(phaseHeader);
108
+ result.push(...dedupeFieldsInPhaseBlock(blockLines));
109
+ phaseHeader = null;
110
+ blockLines = [];
111
+ };
112
+ for (const line of lines) {
113
+ if (/^phases:$/.test(line)) {
114
+ inPhases = true;
115
+ result.push(line);
116
+ continue;
117
+ }
118
+ if (!inPhases) {
119
+ result.push(line);
120
+ continue;
121
+ }
122
+ if (/^\S/.test(line) && !/^ /.test(line)) {
123
+ flushPhase();
124
+ inPhases = false;
125
+ result.push(line);
126
+ continue;
127
+ }
128
+ const keyMatch = line.match(phaseKeyRegex);
129
+ if (keyMatch) {
130
+ flushPhase();
131
+ phaseHeader = line;
132
+ continue;
133
+ }
134
+ if (phaseHeader !== null) {
135
+ blockLines.push(line);
136
+ }
137
+ else {
138
+ result.push(line);
139
+ }
140
+ }
141
+ flushPhase();
142
+ return result.join('\n');
143
+ }
144
+ /** Apply all text-level repairs for agent-corrupted build-state YAML. */
145
+ function repairBuildStateYaml(raw) {
146
+ return quoteUnsafeNextAction(dedupePhaseFields(dedupePhases(raw)));
147
+ }
148
+ /**
149
+ * Quote unquoted next_action scalars that contain colons.
150
+ * Agent text-edits sometimes write "H1: xxx" without quotes, which breaks YAML.
151
+ */
152
+ function quoteUnsafeNextAction(rawYaml) {
153
+ return rawYaml.replace(/^next_action:\s+(?!['">|])(.+)$/gm, (_match, value) => {
154
+ const trimmed = value.trimEnd();
155
+ if (!trimmed.includes(':')) {
156
+ return _match;
157
+ }
158
+ const escaped = trimmed.replace(/'/g, "''");
159
+ return `next_action: '${escaped}'`;
160
+ });
161
+ }
162
+ function parseBuildStateBody(raw) {
163
+ const body = raw.replace(/^#.*\n/gm, '');
164
+ const state = (js_yaml_1.default.load(body) ?? {});
165
+ state.phases = state.phases ?? {};
166
+ return state;
167
+ }
168
+ async function persistBuildStateRaw(statePath, raw) {
169
+ const tmpPath = statePath + '.tmp';
170
+ await fs_extra_1.default.writeFile(tmpPath, raw, 'utf8');
171
+ await fs_extra_1.default.rename(tmpPath, statePath);
172
+ }
63
173
  async function readBuildState(harnessRoot) {
64
174
  const statePath = node_path_1.default.join(harnessRoot, '.harness-build-state.yaml');
65
175
  const raw = await fs_extra_1.default.readFile(statePath, 'utf8');
66
- const body = raw.replace(/^#.*\n/gm, '');
67
176
  try {
68
- const state = (js_yaml_1.default.load(body) ?? {});
69
- state.phases = state.phases ?? {};
70
- return state;
177
+ return parseBuildStateBody(raw);
71
178
  }
72
179
  catch (err) {
73
- // Auto-repair duplicate phase keys (ACP agent text-editing artifact)
74
- if (err instanceof js_yaml_1.default.YAMLException && err.message.includes('duplicated mapping key')) {
75
- const fixed = dedupePhases(raw);
76
- // Persist the fixed content so subsequent reads also succeed
77
- const tmpPath = statePath + '.tmp';
78
- await fs_extra_1.default.writeFile(tmpPath, fixed, 'utf8');
79
- await fs_extra_1.default.rename(tmpPath, statePath);
80
- const fixedBody = fixed.replace(/^#.*\n/gm, '');
81
- const state = (js_yaml_1.default.load(fixedBody) ?? {});
82
- state.phases = state.phases ?? {};
180
+ if (!(err instanceof js_yaml_1.default.YAMLException)) {
181
+ throw err;
182
+ }
183
+ const fixed = repairBuildStateYaml(raw);
184
+ if (fixed === raw) {
185
+ throw err;
186
+ }
187
+ try {
188
+ const state = parseBuildStateBody(fixed);
189
+ await persistBuildStateRaw(statePath, fixed);
83
190
  return state;
84
191
  }
85
- throw err;
192
+ catch {
193
+ throw err;
194
+ }
86
195
  }
87
196
  }
88
197
  async function writeBuildState(harnessRoot, state) {
@@ -13,10 +13,21 @@ const ESSENTIAL_FILES = [
13
13
  'AGENTS_BUILD.md',
14
14
  '.harness-build-state.yaml',
15
15
  ];
16
- async function runMechanicalGates(harnessRoot, verbose = false) {
17
- const doctor_exit = await runDoctorGate(harnessRoot);
16
+ const REQ_PACK_ESSENTIAL = [
17
+ 'harness.yaml',
18
+ '.harness-build-state.yaml',
19
+ 'requirements/raw',
20
+ 'requirements/md',
21
+ 'requirements/yaml',
22
+ 'requirements/_work',
23
+ ];
24
+ async function runMechanicalGates(harnessRoot, opts = {}) {
25
+ const normalized = typeof opts === 'boolean' ? { verbose: opts } : opts;
26
+ const scope = normalized.scope ?? 'full';
27
+ const verbose = normalized.verbose ?? false;
28
+ const doctor_exit = await runDoctorGate(harnessRoot, scope);
18
29
  const verify_exit = await runVerifyGate(harnessRoot, verbose);
19
- const file_completeness_pct = await computeFileCompleteness(harnessRoot);
30
+ const file_completeness_pct = await computeFileCompleteness(harnessRoot, scope);
20
31
  return {
21
32
  doctor_exit,
22
33
  verify_exit,
@@ -24,11 +35,11 @@ async function runMechanicalGates(harnessRoot, verbose = false) {
24
35
  doctor_passed: doctor_exit === 0,
25
36
  };
26
37
  }
27
- async function runDoctorGate(harnessRoot) {
38
+ async function runDoctorGate(harnessRoot, scope) {
28
39
  try {
29
40
  const report = await (0, index_1.runDoctorChecks)({
30
41
  harnessRoot,
31
- mode: 'pre-seal',
42
+ mode: scope === 'requirements' ? 'requirements' : 'pre-seal',
32
43
  strict: true,
33
44
  });
34
45
  return report.passed ? 0 : 1;
@@ -48,11 +59,10 @@ async function runVerifyGate(harnessRoot, verbose) {
48
59
  return 1;
49
60
  }
50
61
  }
51
- async function computeFileCompleteness(harnessRoot) {
52
- const checks = [...ESSENTIAL_FILES];
53
- for (const dir of ['requirements', 'references', 'specs', 'agent-env', 'tasks']) {
54
- checks.push(dir);
55
- }
62
+ async function computeFileCompleteness(harnessRoot, scope) {
63
+ const checks = scope === 'requirements'
64
+ ? [...REQ_PACK_ESSENTIAL]
65
+ : [...ESSENTIAL_FILES, 'requirements', 'references', 'specs', 'agent-env', 'tasks'];
56
66
  let present = 0;
57
67
  for (const rel of checks) {
58
68
  if (await fs_extra_1.default.pathExists(node_path_1.default.join(harnessRoot, rel)))
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PhaseRunner = exports.PHASE_DEFS = void 0;
6
+ exports.PhaseRunner = exports.SCOPE_PHASES = exports.PHASE_DEFS = void 0;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const logger_1 = require("../utils/logger");
@@ -28,6 +28,10 @@ exports.PHASE_DEFS = [
28
28
  { key: 'S70_runtime_assets', short: 'S70', mode: 'acp', promptTemplate: 'S70-runtime-assets.md' },
29
29
  { key: 'S80_seed_memory', short: 'S80', mode: 'acp', promptTemplate: 'S80-seed-memory.md' },
30
30
  ];
31
+ exports.SCOPE_PHASES = {
32
+ full: null,
33
+ requirements: ['S30_convert_docs', 'S40_extract_requirements'],
34
+ };
31
35
  /** 阶段描述映射,供阶段执行时显示给用户了解当前进展。 */
32
36
  const PHASE_DESC = {
33
37
  S10_wiki: '生成 baseline wiki 正文',
@@ -62,7 +66,14 @@ class PhaseRunner {
62
66
  async getBuildPhases() {
63
67
  const harnessRoot = this.ctx.harnessRoot;
64
68
  const state = await (0, auto_state_1.readBuildState)(harnessRoot);
65
- return exports.PHASE_DEFS.filter((def) => def.key in state.phases);
69
+ const allowed = exports.SCOPE_PHASES[this.ctx.scope];
70
+ return exports.PHASE_DEFS.filter((def) => {
71
+ if (!(def.key in state.phases))
72
+ return false;
73
+ if (allowed && !allowed.includes(def.key))
74
+ return false;
75
+ return true;
76
+ });
66
77
  }
67
78
  shouldStopAtMaxPhase(def) {
68
79
  if (!this.ctx.maxPhase)
@@ -13,7 +13,20 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
13
13
  const path_1 = __importDefault(require("path"));
14
14
  const child_process_1 = require("child_process");
15
15
  const logger_1 = require("../utils/logger");
16
- const launch_script_path_1 = require("./launch-script-path");
16
+ /**
17
+ * Resolve absolute path to templates/codechat/Start-CodeChat.ps1 in the installed package.
18
+ */
19
+ function resolveStartCodeChatPs1Path() {
20
+ const fromDist = path_1.default.resolve(__dirname, '..', '..', 'templates', 'codechat', 'Start-CodeChat.ps1');
21
+ if (fs_extra_1.default.existsSync(fromDist)) {
22
+ return fromDist;
23
+ }
24
+ const fromCwd = path_1.default.resolve(__dirname, '..', '..', '..', 'templates', 'codechat', 'Start-CodeChat.ps1');
25
+ if (fs_extra_1.default.existsSync(fromCwd)) {
26
+ return fromCwd;
27
+ }
28
+ throw new Error(`未找到 Start-CodeChat.ps1(预期:${fromDist})`);
29
+ }
17
30
  const START_MARKER = /^#\s*>>>\s*codechat\s*>>>/;
18
31
  const END_MARKER = /^#\s*<<<\s*codechat\s*<<</;
19
32
  function assertWin32() {
@@ -57,8 +70,8 @@ function stripCodechatBlock(content) {
57
70
  const joined = clean.join('\n').replace(/\n+$/, '');
58
71
  return { clean: joined ? `${joined}\n` : '', hadBlock };
59
72
  }
60
- function buildAliasSnippet(launchScriptPath) {
61
- const escapedPath = launchScriptPath.replace(/'/g, "''");
73
+ function buildAliasSnippet(ps1Path) {
74
+ const escapedPath = ps1Path.replace(/'/g, "''");
62
75
  return `
63
76
 
64
77
  # >>> codechat >>>
@@ -69,17 +82,17 @@ function codechat {
69
82
  [string[]]$ExtraArgs
70
83
  )
71
84
  if (-not $Path) { $Path = (Get-Location).Path }
72
- & node '${escapedPath}' "$Path" @ExtraArgs
85
+ & '${escapedPath}' -Action Start -WorkDir "$Path" @ExtraArgs
73
86
  }
74
87
  # <<< codechat <<<
75
88
 
76
89
  `;
77
90
  }
78
- function profileHasSvharnessAlias(content, launchScriptPath) {
91
+ function profileHasSvharnessAlias(content, ps1Path) {
79
92
  if (!START_MARKER.test(content)) {
80
93
  return false;
81
94
  }
82
- const needle = normalizePathForCompare(launchScriptPath);
95
+ const needle = normalizePathForCompare(ps1Path);
83
96
  return normalizePathForCompare(content).includes(needle);
84
97
  }
85
98
  /**
@@ -89,11 +102,11 @@ function profileHasSvharnessAlias(content, launchScriptPath) {
89
102
  async function installCodechatAlias(opts = {}) {
90
103
  assertWin32();
91
104
  const profilePath = getPowerShellProfilePath();
92
- const launchScriptPath = (0, launch_script_path_1.resolveLaunchScriptPath)();
105
+ const ps1Path = resolveStartCodeChatPs1Path();
93
106
  const existing = (await fs_extra_1.default.pathExists(profilePath))
94
107
  ? await fs_extra_1.default.readFile(profilePath, 'utf8')
95
108
  : '';
96
- if (profileHasSvharnessAlias(existing, launchScriptPath)) {
109
+ if (profileHasSvharnessAlias(existing, ps1Path)) {
97
110
  if (!opts.silent) {
98
111
  logger_1.logger.info(`PowerShell 别名 codechat 已存在:${profilePath}`);
99
112
  }
@@ -104,11 +117,11 @@ async function installCodechatAlias(opts = {}) {
104
117
  await fs_extra_1.default.writeFile(profilePath, '', 'utf8');
105
118
  }
106
119
  const { clean, hadBlock } = stripCodechatBlock(existing);
107
- const snippet = buildAliasSnippet(launchScriptPath);
120
+ const snippet = buildAliasSnippet(ps1Path);
108
121
  await fs_extra_1.default.writeFile(profilePath, `${clean}${snippet}`, 'utf8');
109
122
  if (!opts.silent) {
110
123
  if (hadBlock) {
111
- logger_1.logger.success(`已更新 PowerShell 别名 codechat → ${launchScriptPath}`);
124
+ logger_1.logger.success(`已更新 PowerShell 别名 codechat → ${ps1Path}`);
112
125
  }
113
126
  else {
114
127
  logger_1.logger.success(`已安装 PowerShell 别名 codechat → ${profilePath}`);
@@ -144,24 +157,24 @@ async function uninstallCodechatAlias(opts = {}) {
144
157
  function getCodechatAliasStatus() {
145
158
  assertWin32();
146
159
  const profilePath = getPowerShellProfilePath();
147
- let launchScriptPath = '';
160
+ let ps1Path = '';
148
161
  try {
149
- launchScriptPath = (0, launch_script_path_1.resolveLaunchScriptPath)();
162
+ ps1Path = resolveStartCodeChatPs1Path();
150
163
  }
151
164
  catch {
152
- launchScriptPath = '(未找到)';
165
+ ps1Path = '(未找到)';
153
166
  }
154
167
  let installed = false;
155
- if (fs_extra_1.default.existsSync(profilePath) && launchScriptPath !== '(未找到)') {
168
+ if (fs_extra_1.default.existsSync(profilePath) && ps1Path !== '(未找到)') {
156
169
  try {
157
170
  const content = fs_extra_1.default.readFileSync(profilePath, 'utf8');
158
- installed = profileHasSvharnessAlias(content, launchScriptPath);
171
+ installed = profileHasSvharnessAlias(content, ps1Path);
159
172
  }
160
173
  catch {
161
174
  installed = false;
162
175
  }
163
176
  }
164
- return { profilePath, installed, launchScriptPath };
177
+ return { profilePath, installed, launchScriptPath: ps1Path };
165
178
  }
166
179
  function printCodechatAliasStatus() {
167
180
  const status = getCodechatAliasStatus();
@@ -3,10 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseReportFrontmatter = parseReportFrontmatter;
6
7
  exports.parseReviewReport = parseReviewReport;
8
+ exports.parseGapsFromMarkdown = parseGapsFromMarkdown;
7
9
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
10
  const js_yaml_1 = __importDefault(require("js-yaml"));
9
11
  const score_aggregator_1 = require("./score-aggregator");
12
+ async function parseReportFrontmatter(reportPath) {
13
+ if (!(await fs_extra_1.default.pathExists(reportPath)))
14
+ return null;
15
+ const content = await fs_extra_1.default.readFile(reportPath, 'utf8');
16
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
17
+ if (!match)
18
+ return null;
19
+ return js_yaml_1.default.load(match[1]);
20
+ }
10
21
  async function parseReviewReport(reportPath) {
11
22
  if (!(await fs_extra_1.default.pathExists(reportPath)))
12
23
  return null;
@@ -51,6 +62,9 @@ function asRecord(value) {
51
62
  return typeof value === 'object' && value !== null ? value : {};
52
63
  }
53
64
  function parseGaps(content) {
65
+ return parseGapsFromMarkdown(content);
66
+ }
67
+ function parseGapsFromMarkdown(content) {
54
68
  const gaps = [];
55
69
  const lines = content.split(/\r?\n/);
56
70
  for (const line of lines) {
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.computeMechanicalScore = computeMechanicalScore;
4
4
  exports.computeReviewScore = computeReviewScore;
5
5
  exports.computeCompositeScore = computeCompositeScore;
6
+ exports.computeReqPackMechanicalScore = computeReqPackMechanicalScore;
7
+ exports.computeReqPackScore = computeReqPackScore;
6
8
  const REVIEW_INTERNAL_WEIGHTS = {
7
9
  wiki: 15 / 90,
8
10
  requirements: 20 / 90,
@@ -37,6 +39,25 @@ function computeCompositeScore(review) {
37
39
  composite: roundScore(clamp(mechanical * 0.30 + reviewScore * 0.70, 0, 10)),
38
40
  };
39
41
  }
42
+ /** auto_pack_req:硬门禁全通过=10,否则=0 */
43
+ function computeReqPackMechanicalScore(gates, criticalCount) {
44
+ if (gates.doctor_exit !== 0 || gates.verify_exit !== 0 || criticalCount > 0) {
45
+ return 0;
46
+ }
47
+ return 10;
48
+ }
49
+ /** auto_pack_req 三维度综合分:机械 40% + 对抗 30% + 抽样 30% */
50
+ function computeReqPackScore(gates, adversarialAverage, sampleTraceAverage, criticalCount) {
51
+ const mechanical = computeReqPackMechanicalScore(gates, criticalCount);
52
+ const adversarial = clamp(adversarialAverage, 0, 10);
53
+ const sample_trace = clamp(sampleTraceAverage, 0, 10);
54
+ const composite = roundScore(clamp(mechanical * 0.40 + adversarial * 0.30 + sample_trace * 0.30, 0, 10));
55
+ const gate_pass = gates.doctor_exit === 0 &&
56
+ gates.verify_exit === 0 &&
57
+ criticalCount === 0 &&
58
+ mechanical > 0;
59
+ return { mechanical, adversarial, sample_trace, composite, gate_pass };
60
+ }
40
61
  function clamp(value, min, max) {
41
62
  if (!Number.isFinite(value))
42
63
  return min;
@@ -86,4 +86,4 @@ function regKeyExists(key) {
86
86
  }
87
87
  exports.SHELL_MENU_KEY_BG = 'HKCU\\Software\\Classes\\Directory\\Background\\shell\\SvharnessLaunchCodeChatAgent';
88
88
  exports.SHELL_MENU_KEY_DIR = 'HKCU\\Software\\Classes\\Directory\\shell\\SvharnessLaunchCodeChatAgent';
89
- exports.SHELL_MENU_LABEL = '在此启动 CodeChat CLI';
89
+ exports.SHELL_MENU_LABEL = 'Launch CodeChat CLI here';
@@ -13,6 +13,7 @@ exports.resolveConvertPaths = resolveConvertPaths;
13
13
  exports.validateConvertArgs = validateConvertArgs;
14
14
  const fs_extra_1 = __importDefault(require("fs-extra"));
15
15
  const node_path_1 = __importDefault(require("node:path"));
16
+ const convert_1 = require("../constants/convert");
16
17
  const harness_name_1 = require("./harness-name");
17
18
  const SUPPORTED_ARCHES = [
18
19
  'android-compose',
@@ -161,7 +162,7 @@ function listSupportedAgents() {
161
162
  }
162
163
  const DEFAULT_CONCURRENCY = 3;
163
164
  const DEFAULT_MAX_FILE_MB = 50;
164
- const DEFAULT_TIMEOUT_SEC = 120;
165
+ const DEFAULT_TIMEOUT_SEC = convert_1.DEFAULT_CONVERT_TIMEOUT_SEC;
165
166
  const DEFAULT_ENDPOINT = 'http://markitdown.desaysz.site';
166
167
  const ENV_ENDPOINT = 'SVHARNESS_MARKITDOWN_ENDPOINT';
167
168
  const DEFAULT_CONVERT_TYPE = 'requirements';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svharness",
3
- "version": "0.15.11",
3
+ "version": "0.15.13",
4
4
  "description": "CLI scaffolder for SDD-Driven Agent-Agnostic Coding Framework (harness)",
5
5
  "bin": {
6
6
  "svharness": "./bin/cli.js",
@@ -27,9 +27,10 @@
27
27
  "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
28
28
  "rebuild": "npm run clean && npm run build",
29
29
  "test:requirements": "npm run build && node scripts/test-parse-blocks.js",
30
- "test:auto": "npm run build && node scripts/test-auto-score.js && node scripts/test-auto-prompt.js",
30
+ "test:auto": "npm run build && node scripts/test-auto-score.js && node scripts/test-auto-prompt.js && node scripts/test-acp-agent-cli-resolver.js && node scripts/test-auto-pack-req-context.js",
31
31
  "test:cli-declarations": "npm run build && node scripts/test-cli-input-declarations.js",
32
32
  "test:agent-launcher": "npm run build && node scripts/test-agent-launcher.js",
33
+ "test:acp-agent-cli": "npm run build && node scripts/test-acp-agent-cli-resolver.js",
33
34
  "prepare": "npm run build",
34
35
  "postinstall": "node scripts/postinstall.js",
35
36
  "preuninstall": "node scripts/preuninstall.js",