@dzhechkov/harness-cli 0.7.5 → 0.7.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"known-flags.d.ts","sourceRoot":"","sources":["../src/known-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAuR5C,CAAC"}
1
+ {"version":3,"file":"known-flags.d.ts","sourceRoot":"","sources":["../src/known-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAwR5C,CAAC"}
@@ -135,6 +135,7 @@ export const KNOWN_CLI_FLAGS = [
135
135
  'margin',
136
136
  'mark',
137
137
  'max',
138
+ 'max-per-day',
138
139
  'max-wall-clock',
139
140
  'memory',
140
141
  'mock',
@@ -1 +1 @@
1
- {"version":3,"file":"known-flags.js","sourceRoot":"","sources":["../src/known-flags.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"known-flags.js","sourceRoot":"","sources":["../src/known-flags.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/harness-cli",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "The dz CLI — install AI skills for Claude Code, Codex, OpenCode, Hermes, OpenClaude, GitHub Copilot. 67 commands, 14 presets, 10 platform targets.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,23 +41,23 @@
41
41
  "sbom.json"
42
42
  ],
43
43
  "dependencies": {
44
- "@dzhechkov/harness-core": "^0.7.5",
44
+ "@dzhechkov/harness-core": "^0.7.7",
45
45
  "@dzhechkov/scout": "^0.8.7",
46
- "@dzhechkov/harness-presets": "^0.5.14",
47
- "@dzhechkov/skills-mcp": "^0.3.6",
48
46
  "@dzhechkov/skills-devops": "^0.3.13",
47
+ "@dzhechkov/skills-mcp": "^0.3.6",
48
+ "@dzhechkov/harness-presets": "^0.5.14",
49
49
  "@dzhechkov/skills-web3": "^0.2.5",
50
+ "@dzhechkov/skills-meta": "^0.9.50",
50
51
  "@dzhechkov/skills-qe": "^0.3.10",
51
- "@dzhechkov/skills-news": "^0.1.12",
52
52
  "@dzhechkov/skills-ecc": "^0.1.8",
53
- "@dzhechkov/skills-meta": "^0.9.49",
54
- "@dzhechkov/skills-pm": "^0.1.1",
55
53
  "@dzhechkov/skills-academic": "^0.3.3",
54
+ "@dzhechkov/skills-news": "^0.1.12",
55
+ "@dzhechkov/skills-pm": "^0.1.1",
56
56
  "@dzhechkov/skills-taste": "^0.1.1",
57
+ "@dzhechkov/skills-idea2prd": "^0.1.11",
57
58
  "@dzhechkov/skills-reverse-engineering": "^0.1.9",
58
59
  "@dzhechkov/skills-presentation-storyteller": "^0.1.10",
59
- "@dzhechkov/skills-website-cloner": "^0.1.1",
60
- "@dzhechkov/skills-idea2prd": "^0.1.11"
60
+ "@dzhechkov/skills-website-cloner": "^0.1.1"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/node": "^25.6.0",
package/sbom.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "hashes": [
26
26
  {
27
27
  "alg": "SHA-256",
28
- "content": "bf6ac920e20f4e9978dbb7b1cca48790d97e44f245dc53088e189776b4a7616e"
28
+ "content": "ba98f7078023a6202a8bf809b83ae20ef44b3d2e1ca14ce0ae5aac83ffd8d51e"
29
29
  }
30
30
  ]
31
31
  },
@@ -125,7 +125,7 @@
125
125
  "hashes": [
126
126
  {
127
127
  "alg": "SHA-256",
128
- "content": "6fc728a98d8a920a226a4ee2d8b045ee46e27246c7d7e8bdf15e6c7758f3efbc"
128
+ "content": "3c0a60e8d8528e1b7df6bf5678388ce14d3ac3d0362bde42bc8e7e712d914dbd"
129
129
  }
130
130
  ]
131
131
  },
@@ -135,7 +135,7 @@
135
135
  "hashes": [
136
136
  {
137
137
  "alg": "SHA-256",
138
- "content": "4bc5e7cb6563fd672fd7e2c38eac4ba55d54de46940c194b3d2cd5ea4519732a"
138
+ "content": "f117e676f0a120e1314f3cc6416901931d9b389d97052985e1150fa75322b221"
139
139
  }
140
140
  ]
141
141
  },
@@ -145,7 +145,7 @@
145
145
  "hashes": [
146
146
  {
147
147
  "alg": "SHA-256",
148
- "content": "560d103ce98af8095eb7ee86537aa80de7a914fffa693dc23fdf2440a4f76183"
148
+ "content": "718f0380983cb995fad2a30b87af79feb3b0c85656449957bada67956e7e8854"
149
149
  }
150
150
  ]
151
151
  },
@@ -285,7 +285,7 @@
285
285
  "hashes": [
286
286
  {
287
287
  "alg": "SHA-256",
288
- "content": "23fa9b92489e2f39d99397a57f99a4c7566d41b75682d1bbde3f113c480acdcd"
288
+ "content": "93d7a002824ed631f1459e922ac2cad08772e06a21777b64eed095933dd0e889"
289
289
  }
290
290
  ]
291
291
  },
@@ -295,7 +295,7 @@
295
295
  "hashes": [
296
296
  {
297
297
  "alg": "SHA-256",
298
- "content": "f4ed9bddb45629484baf117a3b92eb4097932abda6e5a48227acbc7b5f23f561"
298
+ "content": "64928f5f20cc647f86323b4d179c614613635eeb6a553fd7733bf5ebad653d70"
299
299
  }
300
300
  ]
301
301
  },
@@ -305,7 +305,7 @@
305
305
  "hashes": [
306
306
  {
307
307
  "alg": "SHA-256",
308
- "content": "41bce9592c8192431f7f023271eaf3f548398e5c15441ea69a59e78633915cd9"
308
+ "content": "3cb9b072c57a3d9562cfb919c11c2b242db215169a4675b9940de46b67e0ccfa"
309
309
  }
310
310
  ]
311
311
  },
@@ -335,7 +335,7 @@
335
335
  "hashes": [
336
336
  {
337
337
  "alg": "SHA-256",
338
- "content": "423120966d33fb4515177a7613f0ace5b392a576098987d0d9ca22aedea96716"
338
+ "content": "4831c7b0121cb2a62464bc4d4844e6037a80f9e2d1e6e0934836bde14a1bffdb"
339
339
  }
340
340
  ]
341
341
  },
@@ -365,7 +365,7 @@
365
365
  "hashes": [
366
366
  {
367
367
  "alg": "SHA-256",
368
- "content": "cae511b9b892c43e874ee06b439306290cd2c0a9e6b75cd0cd931d47adaef3f5"
368
+ "content": "f30fb7c6b0795758578a90de19b870c4cde42eb2009fa246051023f499374c09"
369
369
  }
370
370
  ]
371
371
  },
@@ -405,7 +405,7 @@
405
405
  "hashes": [
406
406
  {
407
407
  "alg": "SHA-256",
408
- "content": "aed996e8a3741b595eba31ef694ec5b2999dc0a73933a4289325cf6b9944e254"
408
+ "content": "b08dc5d28795419f642df56fbf5cd036a43a06bb1bec5e864f4e538b0a025b13"
409
409
  }
410
410
  ]
411
411
  }
package/src/cli.ts CHANGED
@@ -452,6 +452,7 @@ import {
452
452
  decideReadBack,
453
453
  recordVerdictLine,
454
454
  buildCadenceReport,
455
+ tgVisibleSha256,
455
456
  CADENCE_WINDOW_DAYS,
456
457
  } from '@dzhechkov/harness-core';
457
458
  import type { RecordKind, RecordDecision } from '@dzhechkov/harness-core';
@@ -498,6 +499,7 @@ Usage:
498
499
  dz release [--filter <name>] [--tag] [--publish] [--json] [--dry-run] [--no-issue] (VERIFIED release: 4 HARD gates in FRONT of dz publish — full package test suites, audit >=high, node --check of every dist/bin file, bin smoke-boot via "node <bin> --help" — any red gate STOPS the release (exit 1) + best-effort gh issue; all green ⇒ re-sign reminder, then prints the ready dz publish command (or chains with --publish); never duplicates publish's own gates)
499
500
  dz parity [--target <name>] [--json] (the honest feature×target map, COMPUTED from the capability model — which harness feature is full / manual / absent on each of the ${TARGET_NAMES.length} targets, and via which form)
500
501
  dz delivery-check --slug <slug> [--context-only] [--findings <f.json>] [--strict] [--author <model>] [--json] (portable Step-10 Delivery Gate: prints the 4-plane review brief + artifact probes; --findings classifies a fed-back review into a fail-closed ready|blocked hand-off and writes features/<slug>/10_delivery_review.md; --strict exits 1 on blocked)
502
+ dz challenge --plan <plan.md> [--author <model>] (the deterministic cartridge behind the challenge-panel adversarial plan-gate (R6): assembles the wide brief — plan + architecture/vision.md + testing.md + map.json + degradations.md — and prints the C1-C8 adversary prompt naming the cross-family reviewer to dispatch. exit 0 brief printed / 1 plan missing or empty)
501
503
  dz skills-verify [--dir <project>] [--expect a,b] [--static] [--strict] [--json] (does .claude/skills/ actually REGISTER? --static = instant layout scan for CI; default reads the authoritative system/init listing from a real session. exit 0 pass / 1 fail / 2 inconclusive — never a false pass)
502
504
  dz compounding [--project <dir>] [--json] (honest learning-loop payoff report: pool write-only ratio, guard repeat-violation trajectory, cold-vs-warm replay readiness, instrumentation health — a gate without enough data says INSUFFICIENT_DATA, never a fake verdict)
503
505
  dz epoch-replay --mock [--n <N>] [--effect <-1..1>] [--tie-rate <0..1>] [--seed <N>] [--slice <name>] [--json] ($0 synthetic run — exercises the verdict math, NOT evidence)
@@ -7229,7 +7231,7 @@ function gatherGuardFacts(op: string, root: string, text: string | undefined, st
7229
7231
  }
7230
7232
  facts['licenceHold'] = holds;
7231
7233
  } catch { /* unreadable tree — the rule reports nothing rather than inventing a violation */ }
7232
- try { facts['drift'] = sweepSkillDrift(root, { scope: 'packages', allowlist: readDriftAllowlist(root) }).drifted.map((d) => d.name); } catch { /* skip */ }
7234
+ try { facts['drift'] = sweepSkillDrift(root, { scope: 'installs', allowlist: readDriftAllowlist(root) }).drifted.map((d) => d.name); } catch { /* skip */ }
7233
7235
  facts['counts'] = gatherReadmeCounts(root);
7234
7236
  // readme-first: from the WORKING-TREE diff (publishes happen pre-commit here), per package: does the
7235
7237
  // change set contain its package.json (the version-bump signal) without its README.md?
@@ -7393,7 +7395,7 @@ function gatherGuardFacts(op: string, root: string, text: string | undefined, st
7393
7395
  if (Array.isArray(stubWaivers)) facts['stubWaivers'] = stubWaivers;
7394
7396
  }
7395
7397
  if (op === 'consolidate') {
7396
- try { facts['drift'] = sweepSkillDrift(root, { scope: 'packages', allowlist: readDriftAllowlist(root) }).drifted.map((d) => d.name); } catch { /* skip */ }
7398
+ try { facts['drift'] = sweepSkillDrift(root, { scope: 'installs', allowlist: readDriftAllowlist(root) }).drifted.map((d) => d.name); } catch { /* skip */ }
7397
7399
  }
7398
7400
  if (op === 'teach' || op === 'consolidate') {
7399
7401
  if (op === 'teach' && text) facts['secretTargets'] = [{ label: 'lesson', text }];
@@ -10396,12 +10398,39 @@ async function cmdTgPost(options: Map<string, string>, flags: Set<string>, cwd:
10396
10398
  if (!json) for (const line of renderSourceProvenance(decision)) write(line);
10397
10399
  }
10398
10400
 
10401
+ // ADR-005 autopublish guards: read the stop-cord and the send journal as FACTS, then let the pure
10402
+ // decideTgSend judge. An UNREADABLE journal stays undefined ⇒ decideTgSend fails closed on G4/G5.
10403
+ const tgDir = join(repoRoot, '.dz', 'tg-post');
10404
+ const halted = existsSync(join(tgDir, 'HALT'));
10405
+ const sha256 = tgVisibleSha256(draft);
10406
+ let sentLog: { sha256: string; ts: string; status?: 'pending' | 'sent' }[] | undefined;
10407
+ const sentLogPath = join(tgDir, 'sent-log.jsonl');
10408
+ if (!existsSync(sentLogPath)) {
10409
+ sentLog = []; // no journal yet is an EMPTY journal, not an unreadable one — a fresh channel sends
10410
+ } else {
10411
+ try {
10412
+ sentLog = [];
10413
+ for (const line of readFileSync(sentLogPath, 'utf-8').split('\n')) {
10414
+ if (line.trim() === '') continue;
10415
+ const r = JSON.parse(line) as { sha256?: unknown; ts?: unknown; status?: unknown };
10416
+ if (typeof r.sha256 === 'string' && typeof r.ts === 'string') {
10417
+ sentLog.push({ sha256: r.sha256, ts: r.ts, ...(r.status === 'pending' || r.status === 'sent' ? { status: r.status } : {}) });
10418
+ }
10419
+ }
10420
+ } catch {
10421
+ sentLog = undefined; // genuinely unreadable ⇒ fail-closed
10422
+ }
10423
+ }
10399
10424
  const decision = decideTgSend({
10400
10425
  issues,
10401
10426
  provenanceOutcome,
10402
10427
  confirmed: flags.has('send') && flags.has('yes'),
10403
10428
  nowUtcIso: new Date().toISOString(),
10404
10429
  nightOverride: flags.has('night'),
10430
+ halted,
10431
+ sha256,
10432
+ sentLog,
10433
+ maxPostsPerDay: (() => { const n = Number(options.get('max-per-day')); return Number.isFinite(n) && n > 0 ? n : 10; })(),
10405
10434
  });
10406
10435
 
10407
10436
  const visible = tgVisibleLength(draft);
@@ -10422,6 +10451,13 @@ async function cmdTgPost(options: Map<string, string>, flags: Set<string>, cwd:
10422
10451
  const channel = (options.get('channel') ?? '').trim();
10423
10452
  if (channel === '') { write('dz tg-post: --channel @name (or a chat id) is required to send'); return 2; }
10424
10453
 
10454
+ // Two-phase journal (Codex A-): write a PENDING row BEFORE the network call. If the process dies
10455
+ // between send and the sent-row, G5 dedup sees this pending row on the next run and refuses to
10456
+ // double-publish. Best-effort — a pending-write failure is warned, not fatal (better to risk one
10457
+ // duplicate than to block a legitimate send on a full disk).
10458
+ try { mkdirSync(tgDir, { recursive: true }); appendFileSync(sentLogPath, JSON.stringify({ sha256, ts: new Date().toISOString(), channel, status: 'pending' }) + '\n'); }
10459
+ catch (e) { write(`dz tg-post: WARNING — could not write the PENDING journal row (${(e as Error).message}); the crash-window dedup guard is degraded for this send`); }
10460
+
10425
10461
  const sent = await tgApi(token, 'sendMessage', {
10426
10462
  chat_id: channel,
10427
10463
  text: draft,
@@ -10434,6 +10470,15 @@ async function cmdTgPost(options: Map<string, string>, flags: Set<string>, cwd:
10434
10470
  if (json) write(JSON.stringify({ ok: false, action: 'send', reason: sent.description ?? 'refused', visible }));
10435
10471
  return 1;
10436
10472
  }
10473
+ // Record the send AFTER Telegram accepted it (never before — a failed send must not eat the daily
10474
+ // limit or block a retry via dedup). Best-effort append; a journal write failure is logged, not
10475
+ // fatal — the post already went out.
10476
+ try {
10477
+ mkdirSync(tgDir, { recursive: true });
10478
+ appendFileSync(sentLogPath, JSON.stringify({ sha256, ts: new Date().toISOString(), channel, messageId: sent.messageId ?? null, status: 'sent' }) + '\n');
10479
+ } catch (e) {
10480
+ write(`dz tg-post: WARNING — sent, but could not record it in ${sentLogPath} (${(e as Error).message}) — the daily limit and dedup may under-count until fixed`);
10481
+ }
10437
10482
  write(`dz tg-post: sent to ${channel}${sent.messageId !== undefined ? ` (message ${sent.messageId})` : ''}`);
10438
10483
  if (json) write(JSON.stringify({ ok: true, action: 'send', channel, messageId: sent.messageId ?? null, visible }));
10439
10484
  return 0;
@@ -135,6 +135,7 @@ export const KNOWN_CLI_FLAGS: readonly string[] = [
135
135
  'margin',
136
136
  'mark',
137
137
  'max',
138
+ 'max-per-day',
138
139
  'max-wall-clock',
139
140
  'memory',
140
141
  'mock',