@dzhechkov/harness-cli 0.3.242 → 0.3.243
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/.dz-manifest.json +7 -7
- package/README.md +16 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +55 -5
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/sbom.json +6 -6
- package/src/cli.ts +55 -4
package/.dz-manifest.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "README.md",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "5f4e31653970ef6970b6d87c862a1c6ac1f2da92c3f4f913b4be4155284db1f4"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "coverage/coverage-final.json",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"path": "dist/cli.d.ts.map",
|
|
44
|
-
"sha256": "
|
|
44
|
+
"sha256": "2bb00d2f42334250ee57b4d0f88d92968cbe3f010ec8d75bb748c0ee6f8de0b8"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": "dist/cli.js",
|
|
48
|
-
"sha256": "
|
|
48
|
+
"sha256": "d959d7623b68286e440e04f90ee3ae7af0166c1fe506f2cf7e6e9e317439409d"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"path": "dist/cli.js.map",
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "68e0bbf621169f7bae350a5b723f9425969ab12b6f7dd98ce26bb06d32c77c92"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "dist/index.d.ts",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"path": "package.json",
|
|
76
|
-
"sha256": "
|
|
76
|
+
"sha256": "e26250419d70ec922def52f25f63000b658eec8203b29a2135edad1be98f8d5d"
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"path": "src/bin.ts",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"path": "src/cli.ts",
|
|
84
|
-
"sha256": "
|
|
84
|
+
"sha256": "14a3db7155fcc858272439a55bc7a43a09c7f6fd7caa302e5a13c153fe1a6d16"
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
"path": "src/index.ts",
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
}
|
|
102
102
|
]
|
|
103
103
|
},
|
|
104
|
-
"signature": "
|
|
104
|
+
"signature": "gGmbCW5Q8VH8CPNbUxHMrZBTxa6wqihi7F0bfUw+dyfN09I/hBQJZzhkautvL4TeFLGJGxkzzXVvpBqjoLHEAw=="
|
|
105
105
|
}
|
package/README.md
CHANGED
|
@@ -517,6 +517,22 @@ binary, a login prompt, a timeout, or a session that read a *different* project
|
|
|
517
517
|
missing, so its listing is refused rather than believed.) A layout so broken that nothing is
|
|
518
518
|
registrable fails too, instead of passing vacuously on an empty expectation.
|
|
519
519
|
|
|
520
|
+
**Registration is not usability — `--live-content`.** A skill can be in the session listing and still
|
|
521
|
+
be unusable content. That was the third, manual step of the health-advisor verification: invoke it and
|
|
522
|
+
check the model really loaded its `SKILL.md`. `--live-content` automates it — an extra turn that asks a
|
|
523
|
+
live model to name the expected skills and **quote a heading verbatim** from one:
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
$ dz skills-verify --expect api-design,debugging,explore --live-content
|
|
527
|
+
dz skills-verify: PASS — all 3 expected skill(s) are registered
|
|
528
|
+
content probe (ADVISORY, model-mediated — never a gate): coherent — every probed skill was named and one was quoted
|
|
529
|
+
quoted: "## When to use"
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
It is **advisory by construction and always will be**: the answer comes from a model, so it never
|
|
533
|
+
changes the exit code and never promotes a verdict. Naming a skill without quoting anything is
|
|
534
|
+
`partial` (naming is not proof the content loaded); an empty answer is `unreadable`, not a pass.
|
|
535
|
+
|
|
520
536
|
**Use it when:** publishing a package that installs skills, after `dz setup` in a new project, or in
|
|
521
537
|
CI (`--static` needs no Claude session at all).
|
|
522
538
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwRH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACvD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA20L9E,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAoJ5E"}
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
9
9
|
import { execSync, spawn } from 'node:child_process';
|
|
10
10
|
import { homedir, tmpdir } from 'node:os';
|
|
11
11
|
import { createRequire } from 'node:module';
|
|
12
|
-
import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, benchmarkSkill, benchmarkSkills, scanMcp, reconcileCapabilities, RECONCILE_BANNER, buildRegistry, discoverSkillPackDirs, checkUpstream, compareSkills, checkAllUpstream, sweepSkillDrift, syncCanonicalSkill, checkUpgrades, discoverPackages, discoverSourcePackages, fetchAllDownloads, filterByCategory, pretrain, recommend, generatePlugin, publishPackages, runSetup, runMigrate, searchRegistry, runSync, runVerify, runInitAgentsMd, runInitGeminiMd, TARGET_NAMES, buildParityMatrix, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, parseInitFacts, verifyRegistration, findNonRegistrableSkillDirs, registrationExitCode, renderRegistrationReport, } from '@dzhechkov/harness-core';
|
|
12
|
+
import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, benchmarkSkill, benchmarkSkills, scanMcp, reconcileCapabilities, RECONCILE_BANNER, buildRegistry, discoverSkillPackDirs, checkUpstream, compareSkills, checkAllUpstream, sweepSkillDrift, syncCanonicalSkill, checkUpgrades, discoverPackages, discoverSourcePackages, fetchAllDownloads, filterByCategory, pretrain, recommend, generatePlugin, publishPackages, runSetup, runMigrate, searchRegistry, runSync, runVerify, runInitAgentsMd, runInitGeminiMd, TARGET_NAMES, buildParityMatrix, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, registrationExitCode, renderRegistrationReport, } from '@dzhechkov/harness-core';
|
|
13
13
|
import { getPreset, PRESET_NAMES } from '@dzhechkov/harness-presets';
|
|
14
14
|
import { scanGitHub, analyzeRepo, generateReport, deepAnalyze, scanAllSources, ScoutMemory } from '@dzhechkov/scout';
|
|
15
15
|
const USAGE = `dz - DZ cross-platform harness CLI
|
|
@@ -5444,6 +5444,44 @@ function probeInitStream(projectDir, timeoutMs) {
|
|
|
5444
5444
|
});
|
|
5445
5445
|
});
|
|
5446
5446
|
}
|
|
5447
|
+
/** Run a full `claude -p` turn and return its text. Unlike the init probe this NEEDS the answer. */
|
|
5448
|
+
function probeContent(projectDir, prompt, timeoutMs) {
|
|
5449
|
+
return new Promise((resolveProbe) => {
|
|
5450
|
+
const env = { ...process.env };
|
|
5451
|
+
for (const key of PROBE_SCRUB_ENV)
|
|
5452
|
+
delete env[key];
|
|
5453
|
+
env.CLAUDE_PROJECT_DIR = projectDir;
|
|
5454
|
+
let out = '';
|
|
5455
|
+
let err = '';
|
|
5456
|
+
let settled = false;
|
|
5457
|
+
let child;
|
|
5458
|
+
const finish = (error) => {
|
|
5459
|
+
if (settled)
|
|
5460
|
+
return;
|
|
5461
|
+
settled = true;
|
|
5462
|
+
clearTimeout(timer);
|
|
5463
|
+
try {
|
|
5464
|
+
child?.kill('SIGTERM');
|
|
5465
|
+
}
|
|
5466
|
+
catch {
|
|
5467
|
+
/* already gone */
|
|
5468
|
+
}
|
|
5469
|
+
resolveProbe({ text: out, error });
|
|
5470
|
+
};
|
|
5471
|
+
const timer = setTimeout(() => finish(`content probe timed out after ${Math.round(timeoutMs / 1000)}s`), timeoutMs);
|
|
5472
|
+
try {
|
|
5473
|
+
child = spawn('claude', ['-p', prompt, '--output-format', 'text'], { cwd: projectDir, env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
5474
|
+
}
|
|
5475
|
+
catch (error) {
|
|
5476
|
+
finish(`cannot run \`claude\`: ${error instanceof Error ? error.message : String(error)}`);
|
|
5477
|
+
return;
|
|
5478
|
+
}
|
|
5479
|
+
child.stdout?.on('data', (c) => { out += c.toString(); });
|
|
5480
|
+
child.stderr?.on('data', (c) => { err += c.toString(); });
|
|
5481
|
+
child.on('error', (error) => finish(`cannot run \`claude\`: ${error.message}`));
|
|
5482
|
+
child.on('close', () => finish(out.trim() === '' ? err.trim() || 'the content probe produced no output' : null));
|
|
5483
|
+
});
|
|
5484
|
+
}
|
|
5447
5485
|
/**
|
|
5448
5486
|
* `dz skills-verify` — does this project's `.claude/skills/` actually REGISTER? (feature
|
|
5449
5487
|
* skills-verify, ADR-001.) L1 static scan is instant and CI-safe; the live layer reads the
|
|
@@ -5455,13 +5493,15 @@ async function cmdSkillsVerify(options, flags, cwd, write) {
|
|
|
5455
5493
|
write('dz skills-verify [--dir <project>] [--expect a,b] [--static] [--strict] [--timeout <s>] [--json]');
|
|
5456
5494
|
write(' Verifies that a project\'s .claude/skills/ actually register in Claude Code.');
|
|
5457
5495
|
write(' --static layout scan only (no Claude session, CI-safe): flags dirs that can never register');
|
|
5496
|
+
write(' --live-content ADVISORY extra turn: ask a live model to name the skills and quote one, proving');
|
|
5497
|
+
write(' the CONTENT is usable — registration is not usability. Never changes the exit code.');
|
|
5458
5498
|
write(' default also starts a real session and reads the authoritative system/init listing');
|
|
5459
5499
|
write(' exit: 0 pass · 1 fail · 2 inconclusive (--strict makes inconclusive exit 1)');
|
|
5460
5500
|
return 0;
|
|
5461
5501
|
}
|
|
5462
|
-
const allowedFlags = new Set(['json', 'help', 'static', 'strict']);
|
|
5502
|
+
const allowedFlags = new Set(['json', 'help', 'static', 'strict', 'live-content']);
|
|
5463
5503
|
const allowedOptions = new Set(['dir', 'expect', 'timeout']);
|
|
5464
|
-
const usage = ' allowed: --dir <project>, --expect a,b, --timeout <s>, --static, --strict, --json';
|
|
5504
|
+
const usage = ' allowed: --dir <project>, --expect a,b, --timeout <s>, --static, --strict, --live-content, --json';
|
|
5465
5505
|
if (options.has('_positional_0')) {
|
|
5466
5506
|
const message = `unexpected argument "${options.get('_positional_0')}"`;
|
|
5467
5507
|
write(json ? JSON.stringify({ error: message, exitCode: 1 }) : `dz skills-verify: ${message}\n${usage}`);
|
|
@@ -5535,10 +5575,20 @@ async function cmdSkillsVerify(options, flags, cwd, write) {
|
|
|
5535
5575
|
...(options.has('expect') ? { expected } : {}),
|
|
5536
5576
|
}, { resolvePath: canonical });
|
|
5537
5577
|
const exitCode = registrationExitCode(result.verdict, flags.has('strict'));
|
|
5578
|
+
// ADVISORY layer: registration is not usability. Costs a real model turn, so it is opt-in, and it
|
|
5579
|
+
// can never change the exit code — a model-mediated signal must not gate anything.
|
|
5580
|
+
let content = null;
|
|
5581
|
+
if (flags.has('live-content') && result.verdict === 'pass' && expected.length > 0) {
|
|
5582
|
+
const probe = await probeContent(projectDir, buildContentProbePrompt(expected), timeoutMs);
|
|
5583
|
+
content = classifyContentProbe(probe.error === null ? probe.text : '', expected.slice(0, 6));
|
|
5584
|
+
}
|
|
5538
5585
|
if (json)
|
|
5539
|
-
write(JSON.stringify({ mode: 'live', ...result, skillsRoot: scan.skillsRoot, exitCode }, null, 2));
|
|
5540
|
-
else
|
|
5586
|
+
write(JSON.stringify({ mode: 'live', ...result, ...(content ? { contentProbe: content } : {}), skillsRoot: scan.skillsRoot, exitCode }, null, 2));
|
|
5587
|
+
else {
|
|
5541
5588
|
write(renderRegistrationReport(result, scan));
|
|
5589
|
+
if (content)
|
|
5590
|
+
write(renderContentProbe(content));
|
|
5591
|
+
}
|
|
5542
5592
|
return exitCode;
|
|
5543
5593
|
}
|
|
5544
5594
|
function cmdDeliveryCheck(options, flags, cwd, write) {
|