create-quiver 0.17.0 → 0.17.1
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
|
@@ -40,6 +40,10 @@ All notable changes to this project will be documented in this file.
|
|
|
40
40
|
- CLI output now follows the shared Quiver palette and hierarchy while keeping `--json`, CI, no-TTY, and `--no-color` output clean.
|
|
41
41
|
- Command docs now cover human-vs-machine output, selectors, Doctor output, and cross-platform usage.
|
|
42
42
|
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- `ai analyze-project` now shows human TTY progress while provider analysis runs and reports schema validation issues with actionable detail.
|
|
46
|
+
|
|
43
47
|
## [0.14.1] - 2026-05-26
|
|
44
48
|
|
|
45
49
|
### Added
|
package/package.json
CHANGED
|
@@ -165,6 +165,46 @@ function limitList(items, maxItems = 30) {
|
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
function formatAnalyzeProjectIssues(issues = [], maxIssues = 8) {
|
|
169
|
+
const list = Array.isArray(issues) ? issues : [];
|
|
170
|
+
const visible = list.slice(0, maxIssues);
|
|
171
|
+
const lines = visible.map((issue) => {
|
|
172
|
+
const location = issue.path || 'analysis';
|
|
173
|
+
const code = issue.issue || 'invalid';
|
|
174
|
+
const message = issue.message || 'Invalid provider analysis output.';
|
|
175
|
+
return `- ${location}: ${code} - ${message}`;
|
|
176
|
+
});
|
|
177
|
+
const hidden = list.length - visible.length;
|
|
178
|
+
if (hidden > 0) {
|
|
179
|
+
lines.push(`- ... ${hidden} more issue${hidden === 1 ? '' : 's'}`);
|
|
180
|
+
}
|
|
181
|
+
return lines;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function enhanceAnalyzeProjectAnalysisError(error) {
|
|
185
|
+
if (!error || error.code !== 'AI_ANALYZE_PROJECT_INVALID') {
|
|
186
|
+
return error;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const issueLines = formatAnalyzeProjectIssues(error.issues);
|
|
190
|
+
if (issueLines.length === 0) {
|
|
191
|
+
return error;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const wrapped = new Error([
|
|
195
|
+
error.message,
|
|
196
|
+
'Issues:',
|
|
197
|
+
...issueLines,
|
|
198
|
+
'Next safe step: inspect the selected evidence with `npx create-quiver ai analyze-project --deep --dry-run --json`, then rerun live. If provider drift repeats, reduce --max-files or --max-bytes.',
|
|
199
|
+
].join('\n'));
|
|
200
|
+
wrapped.name = error.name;
|
|
201
|
+
wrapped.code = error.code;
|
|
202
|
+
wrapped.cause = error;
|
|
203
|
+
wrapped.issues = error.issues;
|
|
204
|
+
wrapped.details = error.issues;
|
|
205
|
+
return wrapped;
|
|
206
|
+
}
|
|
207
|
+
|
|
168
208
|
function formatAnalyzeProjectFileLine(file) {
|
|
169
209
|
const details = [];
|
|
170
210
|
if (Array.isArray(file.signals) && file.signals.length > 0) {
|
|
@@ -1883,6 +1923,9 @@ async function runAnalyzeProject(repoRoot, options = {}) {
|
|
|
1883
1923
|
const runtimeProfile = resolveRuntimeAgentProfile(repoRoot, role, options, DEFAULT_PLAN_PROVIDER);
|
|
1884
1924
|
const provider = runtimeProfile.provider;
|
|
1885
1925
|
const timeoutMs = normalizeTimeout(options.timeout);
|
|
1926
|
+
const ux = createCommandUx(options);
|
|
1927
|
+
const showProgress = shouldShowHumanProgress(ux, options);
|
|
1928
|
+
const progressTranslator = createTranslator(options.language);
|
|
1886
1929
|
const promptPackage = buildAnalyzeProjectPrompt({
|
|
1887
1930
|
analysisPlan: report,
|
|
1888
1931
|
repoRoot,
|
|
@@ -1893,6 +1936,17 @@ async function runAnalyzeProject(repoRoot, options = {}) {
|
|
|
1893
1936
|
const promptLimit = assertProviderPromptWithinLimit(prompt, options.promptLimitOptions || {});
|
|
1894
1937
|
const privacyPreflight = promptPackage.privacyPreflight;
|
|
1895
1938
|
|
|
1939
|
+
writeProgressChecks(
|
|
1940
|
+
ux,
|
|
1941
|
+
showProgress,
|
|
1942
|
+
plannerProgressTitle(progressTranslator.t('ai.planner.progress.analyze_project'), runtimeProfile, options),
|
|
1943
|
+
[
|
|
1944
|
+
progressTranslator.t('ai.planner.progress.reading_base_docs'),
|
|
1945
|
+
progressTranslator.t('ai.planner.progress.detecting_structure'),
|
|
1946
|
+
progressTranslator.t('ai.planner.progress.preparing_prompt'),
|
|
1947
|
+
],
|
|
1948
|
+
);
|
|
1949
|
+
|
|
1896
1950
|
if (!privacyPreflight.ok) {
|
|
1897
1951
|
const error = new Error(formatError('ai analyze-project privacy preflight failed; provider execution was blocked before sending repository content.'));
|
|
1898
1952
|
error.code = 'AI_ANALYZE_PROJECT_PRIVACY_PREFLIGHT_FAILED';
|
|
@@ -1931,18 +1985,25 @@ async function runAnalyzeProject(repoRoot, options = {}) {
|
|
|
1931
1985
|
|
|
1932
1986
|
let result;
|
|
1933
1987
|
try {
|
|
1934
|
-
result = await (
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1988
|
+
result = await runProviderWithProgress({
|
|
1989
|
+
ux,
|
|
1990
|
+
enabled: showProgress,
|
|
1991
|
+
message: progressTranslator.t('ai.planner.progress.running_agent'),
|
|
1992
|
+
successMessage: progressTranslator.t('ai.planner.progress.agent_finished'),
|
|
1993
|
+
failureMessage: progressTranslator.t('ai.planner.progress.agent_failed'),
|
|
1994
|
+
run: () => (options.runProviderFn || runProvider)(provider, {
|
|
1995
|
+
prompt,
|
|
1996
|
+
cwd: repoRoot,
|
|
1997
|
+
timeoutMs,
|
|
1998
|
+
dryRun: false,
|
|
1999
|
+
probe: options.probe,
|
|
2000
|
+
spawn: options.spawn,
|
|
2001
|
+
tempRoot: options.tempRoot,
|
|
2002
|
+
tempFileName: options.tempFileName,
|
|
2003
|
+
tempFilePrefix: options.tempFilePrefix,
|
|
2004
|
+
...runtimeModelExecutionOptions(runtimeProfile, options),
|
|
2005
|
+
enforceModelSelection: false,
|
|
2006
|
+
}),
|
|
1946
2007
|
});
|
|
1947
2008
|
} catch (error) {
|
|
1948
2009
|
throw annotateProviderError(error, 'analyze-project');
|
|
@@ -1953,10 +2014,15 @@ async function runAnalyzeProject(repoRoot, options = {}) {
|
|
|
1953
2014
|
}
|
|
1954
2015
|
|
|
1955
2016
|
const clean = extractCleanProviderOutput(result, { prompt, projectRoot: repoRoot });
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
2017
|
+
let parsed;
|
|
2018
|
+
try {
|
|
2019
|
+
parsed = parseAnalyzeProjectOutput(clean.cleanOutput, {
|
|
2020
|
+
selectedFiles: report.selected_files,
|
|
2021
|
+
promptFiles: promptPackage.files,
|
|
2022
|
+
});
|
|
2023
|
+
} catch (error) {
|
|
2024
|
+
throw enhanceAnalyzeProjectAnalysisError(error);
|
|
2025
|
+
}
|
|
1960
2026
|
const completedReport = {
|
|
1961
2027
|
...report,
|
|
1962
2028
|
provider,
|
|
@@ -272,6 +272,7 @@ module.exports = {
|
|
|
272
272
|
'ai.plan.with_planner_already_active': 'Planner mode: already active for ai plan; --with-planner is accepted for UX consistency.',
|
|
273
273
|
'ai.planner.progress.agent_failed': 'Agent failed',
|
|
274
274
|
'ai.planner.progress.agent_finished': 'Agent finished',
|
|
275
|
+
'ai.planner.progress.analyze_project': 'Analyzing project',
|
|
275
276
|
'ai.planner.progress.detecting_structure': 'Detecting structure',
|
|
276
277
|
'ai.planner.progress.onboarding': 'Running onboarding',
|
|
277
278
|
'ai.planner.progress.plan': 'Running plan {phase}',
|
|
@@ -387,6 +387,7 @@ module.exports = {
|
|
|
387
387
|
'ai.plan.with_planner_already_active': 'Modo planner: ya esta activo para ai plan; --with-planner se acepta por consistencia de UX.',
|
|
388
388
|
'ai.planner.progress.agent_failed': 'Fallo el agente',
|
|
389
389
|
'ai.planner.progress.agent_finished': 'Agente finalizado',
|
|
390
|
+
'ai.planner.progress.analyze_project': 'Analizando proyecto',
|
|
390
391
|
'ai.planner.progress.detecting_structure': 'Detectando estructura',
|
|
391
392
|
'ai.planner.progress.onboarding': 'Ejecutando onboarding',
|
|
392
393
|
'ai.planner.progress.plan': 'Ejecutando plan {phase}',
|