@nerviq/cli 1.11.0 → 1.13.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/README.md +216 -124
- package/bin/cli.js +620 -183
- package/package.json +3 -2
- package/src/activity.js +49 -9
- package/src/adoption-advisor.js +299 -0
- package/src/aider/freshness.js +65 -20
- package/src/aider/techniques.js +16 -11
- package/src/analyze.js +128 -0
- package/src/anti-patterns.js +13 -0
- package/src/audit/instruction-files.js +180 -0
- package/src/audit/recommendations.js +531 -0
- package/src/audit.js +53 -681
- package/src/behavioral-drift.js +801 -0
- package/src/codex/freshness.js +84 -25
- package/src/continuous-ops.js +681 -0
- package/src/copilot/freshness.js +57 -20
- package/src/cost-tracking.js +61 -0
- package/src/cursor/freshness.js +65 -20
- package/src/cursor/techniques.js +17 -12
- package/src/deep-review.js +83 -0
- package/src/diff-only.js +280 -0
- package/src/doctor.js +118 -55
- package/src/freshness.js +74 -21
- package/src/gemini/freshness.js +66 -21
- package/src/governance.js +59 -43
- package/src/hook-validation.js +342 -0
- package/src/index.js +5 -0
- package/src/integrations.js +42 -5
- package/src/mcp-server.js +95 -59
- package/src/mcp-validation.js +337 -0
- package/src/opencode/freshness.js +66 -21
- package/src/opencode/techniques.js +12 -7
- package/src/operating-profile.js +574 -0
- package/src/org.js +97 -13
- package/src/plans.js +192 -8
- package/src/platform-change-manifest.js +86 -0
- package/src/policy-layers.js +210 -0
- package/src/profiles.js +4 -1
- package/src/prompt-injection.js +74 -0
- package/src/repo-archetype.js +386 -0
- package/src/setup/analysis.js +619 -0
- package/src/setup/runtime.js +172 -0
- package/src/setup.js +62 -748
- package/src/source-urls.js +132 -132
- package/src/supplemental-checks.js +13 -12
- package/src/techniques/api.js +407 -0
- package/src/techniques/automation.js +316 -0
- package/src/techniques/compliance.js +257 -0
- package/src/techniques/hygiene.js +294 -0
- package/src/techniques/instructions.js +243 -0
- package/src/techniques/observability.js +226 -0
- package/src/techniques/optimization.js +142 -0
- package/src/techniques/quality.js +317 -0
- package/src/techniques/security.js +237 -0
- package/src/techniques/shared.js +443 -0
- package/src/techniques/stacks.js +2294 -0
- package/src/techniques/tools.js +106 -0
- package/src/techniques/workflow.js +413 -0
- package/src/techniques.js +78 -5607
- package/src/watch.js +18 -0
- package/src/windsurf/freshness.js +36 -21
- package/src/windsurf/techniques.js +17 -12
package/src/watch.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const { audit } = require('./audit');
|
|
10
|
+
const { detectPlatforms } = require('./public-api');
|
|
11
|
+
const { buildContinuousStatus, formatContinuousStatus } = require('./continuous-ops');
|
|
10
12
|
|
|
11
13
|
const COLORS = {
|
|
12
14
|
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
@@ -131,12 +133,14 @@ function closeWatchers(watchers) {
|
|
|
131
133
|
|
|
132
134
|
async function watch(options) {
|
|
133
135
|
const recursiveSupported = supportsNativeRecursiveWatch();
|
|
136
|
+
const watchMode = options.driftMode || 'watch';
|
|
134
137
|
|
|
135
138
|
console.log('');
|
|
136
139
|
console.log(c(' nerviq watch mode', 'bold'));
|
|
137
140
|
console.log(c(' ═══════════════════════════════════════', 'dim'));
|
|
138
141
|
console.log(c(` Watching: ${options.dir}`, 'dim'));
|
|
139
142
|
console.log(c(` Mode: ${recursiveSupported ? 'native recursive directories' : 'expanded directory fallback (cross-platform safe)'}`, 'dim'));
|
|
143
|
+
console.log(c(` Continuous mode: ${watchMode}`, 'dim'));
|
|
140
144
|
console.log(c(' Press Ctrl+C to stop', 'dim'));
|
|
141
145
|
console.log('');
|
|
142
146
|
|
|
@@ -147,6 +151,13 @@ async function watch(options) {
|
|
|
147
151
|
lastScore = result.score;
|
|
148
152
|
console.log(` ${c('Initial score:', 'bold')} ${scoreColor(result.score)}`);
|
|
149
153
|
console.log(` ${result.passed} / ${result.passed + result.failed} checks passing`);
|
|
154
|
+
const continuousStatus = buildContinuousStatus({
|
|
155
|
+
dir: options.dir,
|
|
156
|
+
auditResult: result,
|
|
157
|
+
mode: watchMode,
|
|
158
|
+
currentPlatforms: detectPlatforms(options.dir),
|
|
159
|
+
});
|
|
160
|
+
console.log(formatContinuousStatus(continuousStatus, { compact: true }));
|
|
150
161
|
console.log('');
|
|
151
162
|
} catch (e) {
|
|
152
163
|
console.log(c(` Initial audit failed: ${e.message}`, 'dim'));
|
|
@@ -184,8 +195,15 @@ async function watch(options) {
|
|
|
184
195
|
const result = await audit({ ...options, silent: true });
|
|
185
196
|
const delta = lastScore !== null ? result.score - lastScore : 0;
|
|
186
197
|
const arrow = delta > 0 ? c(`+${delta}`, 'green') : delta < 0 ? c(String(delta), 'yellow') : '';
|
|
198
|
+
const continuousStatus = buildContinuousStatus({
|
|
199
|
+
dir: options.dir,
|
|
200
|
+
auditResult: result,
|
|
201
|
+
mode: watchMode,
|
|
202
|
+
currentPlatforms: detectPlatforms(options.dir),
|
|
203
|
+
});
|
|
187
204
|
|
|
188
205
|
console.log(` Score: ${scoreColor(result.score)} ${arrow} (${result.passed}/${result.passed + result.failed} passing)`);
|
|
206
|
+
console.log(formatContinuousStatus(continuousStatus, { compact: true }));
|
|
189
207
|
|
|
190
208
|
if (lastScore !== null && result.score > lastScore) {
|
|
191
209
|
console.log(c(' Nice improvement!', 'green'));
|
|
@@ -41,18 +41,25 @@ const P0_SOURCES = [
|
|
|
41
41
|
stalenessThresholdDays: 30,
|
|
42
42
|
verifiedAt: '2026-04-07',
|
|
43
43
|
},
|
|
44
|
-
{
|
|
45
|
-
key: 'windsurf-workflows-docs',
|
|
46
|
-
label: 'Workflows Documentation',
|
|
47
|
-
url: 'https://docs.windsurf.com/windsurf/cascade/workflows',
|
|
48
|
-
stalenessThresholdDays: 30,
|
|
49
|
-
verifiedAt: '2026-04-07',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
key: 'windsurf-
|
|
53
|
-
label: '
|
|
54
|
-
url: 'https://docs.windsurf.com/windsurf/
|
|
55
|
-
stalenessThresholdDays:
|
|
44
|
+
{
|
|
45
|
+
key: 'windsurf-workflows-docs',
|
|
46
|
+
label: 'Workflows Documentation',
|
|
47
|
+
url: 'https://docs.windsurf.com/windsurf/cascade/workflows',
|
|
48
|
+
stalenessThresholdDays: 30,
|
|
49
|
+
verifiedAt: '2026-04-07',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: 'windsurf-models-docs',
|
|
53
|
+
label: 'Windsurf Models & BYOK',
|
|
54
|
+
url: 'https://docs.windsurf.com/windsurf/models',
|
|
55
|
+
stalenessThresholdDays: 14,
|
|
56
|
+
verifiedAt: '2026-04-10',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: 'windsurf-steps-docs',
|
|
60
|
+
label: 'Steps Documentation (via Workflows)',
|
|
61
|
+
url: 'https://docs.windsurf.com/windsurf/cascade/workflows',
|
|
62
|
+
stalenessThresholdDays: 30,
|
|
56
63
|
verifiedAt: '2026-04-07',
|
|
57
64
|
},
|
|
58
65
|
{
|
|
@@ -140,15 +147,23 @@ const PROPAGATION_CHECKLIST = [
|
|
|
140
147
|
'src/windsurf/patch.js — update patchCascadeignore',
|
|
141
148
|
],
|
|
142
149
|
},
|
|
143
|
-
{
|
|
144
|
-
trigger: '10K char rule limit change',
|
|
145
|
-
targets: [
|
|
146
|
-
'src/windsurf/techniques.js — update WS-A05, WS-L05',
|
|
147
|
-
'src/windsurf/context.js — update overLimit calculation',
|
|
148
|
-
'src/windsurf/governance.js — update rule-char-limit caveat',
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
|
|
150
|
+
{
|
|
151
|
+
trigger: '10K char rule limit change',
|
|
152
|
+
targets: [
|
|
153
|
+
'src/windsurf/techniques.js — update WS-A05, WS-L05',
|
|
154
|
+
'src/windsurf/context.js — update overLimit calculation',
|
|
155
|
+
'src/windsurf/governance.js — update rule-char-limit caveat',
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
trigger: 'Windsurf model catalog / BYOK / pricing behavior change',
|
|
160
|
+
targets: [
|
|
161
|
+
'src/windsurf/techniques.js — update model-awareness and cost/trust assumptions',
|
|
162
|
+
'src/windsurf/governance.js — update BYOK and model-selection caveats',
|
|
163
|
+
'src/source-urls.js — refresh Windsurf model source mappings',
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
];
|
|
152
167
|
|
|
153
168
|
/**
|
|
154
169
|
* Release gate: check if all P0 sources are within staleness threshold.
|
|
@@ -26,11 +26,12 @@
|
|
|
26
26
|
const fs = require('fs');
|
|
27
27
|
const os = require('os');
|
|
28
28
|
const path = require('path');
|
|
29
|
-
const { WindsurfProjectContext } = require('./context');
|
|
30
|
-
const { EMBEDDED_SECRET_PATTERNS, containsEmbeddedSecret } = require('../secret-patterns');
|
|
31
|
-
const { attachSourceUrls } = require('../source-urls');
|
|
32
|
-
const { buildStackChecks } = require('../stack-checks');
|
|
33
|
-
const { isApiProject, isDatabaseProject, isAuthProject, isMonitoringRelevant } = require('../supplemental-checks');
|
|
29
|
+
const { WindsurfProjectContext } = require('./context');
|
|
30
|
+
const { EMBEDDED_SECRET_PATTERNS, containsEmbeddedSecret } = require('../secret-patterns');
|
|
31
|
+
const { attachSourceUrls } = require('../source-urls');
|
|
32
|
+
const { buildStackChecks } = require('../stack-checks');
|
|
33
|
+
const { isApiProject, isDatabaseProject, isAuthProject, isMonitoringRelevant } = require('../supplemental-checks');
|
|
34
|
+
const { hasCostBudgetOrUsageTracking } = require('../cost-tracking');
|
|
34
35
|
const { tryParseJson, validateMcpEnvVars } = require('./config-parser');
|
|
35
36
|
|
|
36
37
|
// ─── Shared helpers ─────────────────────────────────────────────────────────
|
|
@@ -2161,13 +2162,17 @@ const WINDSURF_TECHNIQUES = {
|
|
|
2161
2162
|
fix: 'Document prompt caching strategy to reduce Windsurf API costs.',
|
|
2162
2163
|
template: null, file: () => 'AGENTS.md', line: () => null,
|
|
2163
2164
|
},
|
|
2164
|
-
wsCostBudgetDefined: {
|
|
2165
|
-
id: 'WS-T48', name: 'AI cost budget or usage
|
|
2166
|
-
check: (ctx) => {
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2165
|
+
wsCostBudgetDefined: {
|
|
2166
|
+
id: 'WS-T48', name: 'AI cost budget or per-run usage tracking documented',
|
|
2167
|
+
check: (ctx) => {
|
|
2168
|
+
const docs = (ctx.fileContent('AGENTS.md') || '') + (ctx.fileContent('README.md') || '');
|
|
2169
|
+
if (!docs.trim() && !hasCostBudgetOrUsageTracking('', ctx)) return null;
|
|
2170
|
+
return hasCostBudgetOrUsageTracking(docs, ctx);
|
|
2171
|
+
},
|
|
2172
|
+
impact: 'low', rating: 2, category: 'cost-optimization',
|
|
2173
|
+
fix: 'Document AI cost guardrails or per-run usage tracking so Windsurf usage is measurable over time.',
|
|
2174
|
+
template: null, file: () => 'README.md', line: () => null,
|
|
2175
|
+
},
|
|
2171
2176
|
|
|
2172
2177
|
// ============================================================
|
|
2173
2178
|
// === PYTHON STACK CHECKS (category: 'python') ===============
|