@dzhechkov/harness-core 0.8.11 → 0.8.21

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 (205) hide show
  1. package/.dz-manifest.json +399 -139
  2. package/LICENSE +13 -0
  3. package/README.md +420 -6
  4. package/dist/agents-policy.d.ts +15 -1
  5. package/dist/agents-policy.d.ts.map +1 -1
  6. package/dist/agents-policy.js +27 -1
  7. package/dist/agents-policy.js.map +1 -1
  8. package/dist/amendment-trace.d.ts +72 -0
  9. package/dist/amendment-trace.d.ts.map +1 -1
  10. package/dist/amendment-trace.js +385 -17
  11. package/dist/amendment-trace.js.map +1 -1
  12. package/dist/backlog-public.d.ts +153 -0
  13. package/dist/backlog-public.d.ts.map +1 -0
  14. package/dist/backlog-public.js +415 -0
  15. package/dist/backlog-public.js.map +1 -0
  16. package/dist/backlog-transitions.d.ts +48 -0
  17. package/dist/backlog-transitions.d.ts.map +1 -0
  18. package/dist/backlog-transitions.js +64 -0
  19. package/dist/backlog-transitions.js.map +1 -0
  20. package/dist/backlog.d.ts.map +1 -1
  21. package/dist/backlog.js +13 -0
  22. package/dist/backlog.js.map +1 -1
  23. package/dist/claim-check.d.ts.map +1 -1
  24. package/dist/claim-check.js +24 -2
  25. package/dist/claim-check.js.map +1 -1
  26. package/dist/claude-hooks-assets.d.ts +93 -0
  27. package/dist/claude-hooks-assets.d.ts.map +1 -0
  28. package/dist/claude-hooks-assets.js +208 -0
  29. package/dist/claude-hooks-assets.js.map +1 -0
  30. package/dist/clean-room-smoke.d.ts +83 -0
  31. package/dist/clean-room-smoke.d.ts.map +1 -0
  32. package/dist/clean-room-smoke.js +138 -0
  33. package/dist/clean-room-smoke.js.map +1 -0
  34. package/dist/cmd-usage.d.ts.map +1 -1
  35. package/dist/cmd-usage.js +36 -6
  36. package/dist/cmd-usage.js.map +1 -1
  37. package/dist/codex-hooks-assets.d.ts +25 -7
  38. package/dist/codex-hooks-assets.d.ts.map +1 -1
  39. package/dist/codex-hooks-assets.js +138 -30
  40. package/dist/codex-hooks-assets.js.map +1 -1
  41. package/dist/codex-hooks.d.ts +21 -1
  42. package/dist/codex-hooks.d.ts.map +1 -1
  43. package/dist/codex-hooks.js +21 -1
  44. package/dist/codex-hooks.js.map +1 -1
  45. package/dist/course-staleness.d.ts +19 -0
  46. package/dist/course-staleness.d.ts.map +1 -0
  47. package/dist/course-staleness.js +95 -0
  48. package/dist/course-staleness.js.map +1 -0
  49. package/dist/destructive-guard-hook.d.ts +40 -0
  50. package/dist/destructive-guard-hook.d.ts.map +1 -0
  51. package/dist/destructive-guard-hook.js +109 -0
  52. package/dist/destructive-guard-hook.js.map +1 -0
  53. package/dist/destructive-guard.d.ts +27 -0
  54. package/dist/destructive-guard.d.ts.map +1 -0
  55. package/dist/destructive-guard.js +2808 -0
  56. package/dist/destructive-guard.js.map +1 -0
  57. package/dist/discrimination-gate.d.ts +28 -3
  58. package/dist/discrimination-gate.d.ts.map +1 -1
  59. package/dist/discrimination-gate.js +76 -16
  60. package/dist/discrimination-gate.js.map +1 -1
  61. package/dist/feature-adr-routing.d.ts +95 -1
  62. package/dist/feature-adr-routing.d.ts.map +1 -1
  63. package/dist/feature-adr-routing.js +193 -27
  64. package/dist/feature-adr-routing.js.map +1 -1
  65. package/dist/guard.d.ts +90 -0
  66. package/dist/guard.d.ts.map +1 -1
  67. package/dist/guard.js +271 -0
  68. package/dist/guard.js.map +1 -1
  69. package/dist/harness-core-location.d.ts +18 -0
  70. package/dist/harness-core-location.d.ts.map +1 -0
  71. package/dist/harness-core-location.js +42 -0
  72. package/dist/harness-core-location.js.map +1 -0
  73. package/dist/index.d.ts +24 -6
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +24 -3
  76. package/dist/index.js.map +1 -1
  77. package/dist/lead-shift-gate.d.ts +95 -0
  78. package/dist/lead-shift-gate.d.ts.map +1 -0
  79. package/dist/lead-shift-gate.js +100 -0
  80. package/dist/lead-shift-gate.js.map +1 -0
  81. package/dist/ledger-backfill.d.ts +11 -1
  82. package/dist/ledger-backfill.d.ts.map +1 -1
  83. package/dist/ledger-backfill.js +19 -0
  84. package/dist/ledger-backfill.js.map +1 -1
  85. package/dist/loop-blobs.generated.d.ts +1 -1
  86. package/dist/loop-blobs.generated.d.ts.map +1 -1
  87. package/dist/loop-blobs.generated.js +12 -3
  88. package/dist/loop-blobs.generated.js.map +1 -1
  89. package/dist/loop-lint.d.ts.map +1 -1
  90. package/dist/loop-lint.js +56 -7
  91. package/dist/loop-lint.js.map +1 -1
  92. package/dist/loop-plan-graph.d.ts +1 -3
  93. package/dist/loop-plan-graph.d.ts.map +1 -1
  94. package/dist/loop-plan-graph.js +70 -1
  95. package/dist/loop-plan-graph.js.map +1 -1
  96. package/dist/loop-trace.d.ts.map +1 -1
  97. package/dist/loop-trace.js +16 -2
  98. package/dist/loop-trace.js.map +1 -1
  99. package/dist/managed-hooks.d.ts +5 -6
  100. package/dist/managed-hooks.d.ts.map +1 -1
  101. package/dist/managed-hooks.js +2 -2
  102. package/dist/managed-hooks.js.map +1 -1
  103. package/dist/model-recommender.d.ts.map +1 -1
  104. package/dist/model-recommender.js +14 -3
  105. package/dist/model-recommender.js.map +1 -1
  106. package/dist/operations.d.ts.map +1 -1
  107. package/dist/operations.js +82 -0
  108. package/dist/operations.js.map +1 -1
  109. package/dist/patterns.d.ts +23 -0
  110. package/dist/patterns.d.ts.map +1 -1
  111. package/dist/patterns.js +10 -0
  112. package/dist/patterns.js.map +1 -1
  113. package/dist/publish.d.ts +11 -0
  114. package/dist/publish.d.ts.map +1 -1
  115. package/dist/publish.js +16 -2
  116. package/dist/publish.js.map +1 -1
  117. package/dist/registry.d.ts.map +1 -1
  118. package/dist/registry.js +3 -2
  119. package/dist/registry.js.map +1 -1
  120. package/dist/score.d.ts.map +1 -1
  121. package/dist/score.js +15 -4
  122. package/dist/score.js.map +1 -1
  123. package/dist/session-retro.d.ts +121 -2
  124. package/dist/session-retro.d.ts.map +1 -1
  125. package/dist/session-retro.js +454 -11
  126. package/dist/session-retro.js.map +1 -1
  127. package/dist/setup.d.ts +28 -0
  128. package/dist/setup.d.ts.map +1 -1
  129. package/dist/setup.js +223 -6
  130. package/dist/setup.js.map +1 -1
  131. package/dist/sign.d.ts.map +1 -1
  132. package/dist/sign.js +18 -1
  133. package/dist/sign.js.map +1 -1
  134. package/dist/skills-verify.d.ts +34 -1
  135. package/dist/skills-verify.d.ts.map +1 -1
  136. package/dist/skills-verify.js +82 -0
  137. package/dist/skills-verify.js.map +1 -1
  138. package/dist/stage-line.d.ts +68 -0
  139. package/dist/stage-line.d.ts.map +1 -0
  140. package/dist/stage-line.js +129 -0
  141. package/dist/stage-line.js.map +1 -0
  142. package/dist/statusline.d.ts +99 -0
  143. package/dist/statusline.d.ts.map +1 -1
  144. package/dist/statusline.js +310 -44
  145. package/dist/statusline.js.map +1 -1
  146. package/dist/store-counts.d.ts +26 -0
  147. package/dist/store-counts.d.ts.map +1 -0
  148. package/dist/store-counts.js +125 -0
  149. package/dist/store-counts.js.map +1 -0
  150. package/dist/store-guard.d.ts +106 -0
  151. package/dist/store-guard.d.ts.map +1 -0
  152. package/dist/store-guard.js +294 -0
  153. package/dist/store-guard.js.map +1 -0
  154. package/dist/swarm-brief.d.ts +95 -0
  155. package/dist/swarm-brief.d.ts.map +1 -0
  156. package/dist/swarm-brief.js +660 -0
  157. package/dist/swarm-brief.js.map +1 -0
  158. package/dist/trace-bundle.d.ts +8 -0
  159. package/dist/trace-bundle.d.ts.map +1 -1
  160. package/dist/trace-bundle.js +11 -0
  161. package/dist/trace-bundle.js.map +1 -1
  162. package/package.json +12 -11
  163. package/sbom.json +804 -154
  164. package/src/agents-policy.ts +46 -2
  165. package/src/amendment-trace.ts +441 -19
  166. package/src/backlog-public.ts +503 -0
  167. package/src/backlog-transitions.ts +77 -0
  168. package/src/backlog.ts +12 -0
  169. package/src/claim-check.ts +25 -2
  170. package/src/claude-hooks-assets.ts +227 -0
  171. package/src/clean-room-smoke.ts +195 -0
  172. package/src/cmd-usage.ts +29 -5
  173. package/src/codex-hooks-assets.ts +140 -30
  174. package/src/codex-hooks.ts +21 -1
  175. package/src/course-staleness.ts +125 -0
  176. package/src/destructive-guard-hook.ts +151 -0
  177. package/src/destructive-guard.ts +3027 -0
  178. package/src/discrimination-gate.ts +98 -19
  179. package/src/feature-adr-routing.ts +220 -22
  180. package/src/guard.ts +318 -0
  181. package/src/harness-core-location.ts +44 -0
  182. package/src/index.ts +111 -3
  183. package/src/lead-shift-gate.ts +145 -0
  184. package/src/ledger-backfill.ts +20 -1
  185. package/src/loop-blobs.generated.ts +12 -3
  186. package/src/loop-lint.ts +52 -7
  187. package/src/loop-plan-graph.ts +66 -1
  188. package/src/loop-trace.ts +13 -1
  189. package/src/managed-hooks.ts +5 -6
  190. package/src/model-recommender.ts +14 -3
  191. package/src/operations.ts +75 -0
  192. package/src/patterns.ts +33 -0
  193. package/src/publish.ts +27 -2
  194. package/src/registry.ts +3 -2
  195. package/src/score.ts +16 -4
  196. package/src/session-retro.ts +466 -11
  197. package/src/setup.ts +246 -9
  198. package/src/sign.ts +18 -1
  199. package/src/skills-verify.ts +99 -1
  200. package/src/stage-line.ts +151 -0
  201. package/src/statusline.ts +396 -47
  202. package/src/store-counts.ts +154 -0
  203. package/src/store-guard.ts +388 -0
  204. package/src/swarm-brief.ts +661 -0
  205. package/src/trace-bundle.ts +10 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * The Claude-side destructive-command guard, as an INSTALLABLE asset
3
+ * (feature `destructive-command-guard`, task T8, cross-family review round 3, finding P1-1).
4
+ *
5
+ * ## Why this file exists
6
+ *
7
+ * The guard shipped as one file committed at this repository's root, registered in this
8
+ * repository's `.claude/settings.json`. MEASURED 2026-09-05, running the documented command in a
9
+ * clean project — `dz setup --target claude-code --project <tmp>`:
10
+ * the written `.claude/settings.json` carries SessionStart / SessionEnd / PreCompact and no
11
+ * `PreToolUse` key at all, and `.claude/hooks/` does not exist.
12
+ * So the advertised Claude-side guard protected exactly one checkout: ours. A guard that only ever
13
+ * guards its author is a demo.
14
+ *
15
+ * Setup therefore has to install BOTH halves into the consumer project — the body and the registry
16
+ * entry — and the body must come from the INSTALLED package, never from a path inside our
17
+ * repository, which a consumer does not have.
18
+ *
19
+ * ## Why the body carries an absolute path
20
+ *
21
+ * The emitted hook runs from `<consumer>/.claude/hooks/`, where `require('@dzhechkov/harness-core')`
22
+ * cannot resolve: Node resolves a bare specifier upward from the FILE, and the package is not above
23
+ * that file in a global install. The body therefore resolves by PATH, and the LAST candidate is the
24
+ * absolute location of the installation that emitted it (see `harness-core-location.ts` for the
25
+ * measurement that forced this). Project-local candidates come FIRST, so a consumer that installed
26
+ * harness-core itself keeps using its own copy and is never pinned to ours.
27
+ *
28
+ * The generated text is behaviourally identical to this repository's own
29
+ * `.claude/hooks/destructive-guard.cjs`, and a test drives BOTH bodies through the same matrix
30
+ * rather than trusting that they stayed alike.
31
+ *
32
+ * @packageDocumentation
33
+ */
34
+ import { harnessCoreDistDir } from './harness-core-location.js';
35
+ /** Bump when the emitted BODY changes. Unlike Codex, Claude has no trust gate — this is provenance. */
36
+ export const DZ_CLAUDE_HOOK_VERSION = 1;
37
+ /**
38
+ * The OWNERSHIP marker. A file carrying this line is one dz wrote and may replace; a file without it
39
+ * belongs to the consumer and is never overwritten without `--force`.
40
+ *
41
+ * MEASURED 2026-09-05, before this existed: a hand-authored
42
+ * `.claude/hooks/destructive-guard.cjs` was replaced by a routine `dz setup` run, no `--force`
43
+ * involved — the one path in setup that was not additive. Ownership is asserted by a MARKER rather
44
+ * than by a hash of the bytes we wrote, because an UPGRADE must still be able to replace an older
45
+ * dz body; the cost of that choice is stated in the emitted file itself, on the marker line.
46
+ */
47
+ export const CLAUDE_DESTRUCTIVE_HOOK_MARKER = 'dz-managed-hook: destructive-guard';
48
+ /** Is this file body one dz owns? Absence of the marker is the consumer's claim to the file. */
49
+ export function isDzManagedHookBody(body) {
50
+ return body.includes(CLAUDE_DESTRUCTIVE_HOOK_MARKER);
51
+ }
52
+ /** Where the body is installed inside a consumer project, and what the registry entry points at. */
53
+ export const CLAUDE_DESTRUCTIVE_HOOK_RELPATH = '.claude/hooks/destructive-guard.cjs';
54
+ /**
55
+ * The command Claude Code runs — the EXACT documented placeholder, never a shell-only variant.
56
+ *
57
+ * Relative to the project rather than absolute: the settings file is committed by consumers and
58
+ * shared across machines, and an absolute path in it breaks for every collaborator. The BODY may
59
+ * carry an absolute fallback because it is generated per machine; the SETTINGS entry may not.
60
+ *
61
+ * WHY THE EXACT TOKEN [DOC, code.claude.com/docs/en/hooks, read 2026-09-06]. `${CLAUDE_PROJECT_DIR}`
62
+ * is a PLACEHOLDER Claude Code substitutes itself — "Use these placeholders to reference hook
63
+ * scripts relative to the project or plugin root, regardless of the working directory when the hook
64
+ * runs: ${CLAUDE_PROJECT_DIR}: the project root where the session started" — and the documentation
65
+ * describes NO default syntax. The previous `${CLAUDE_PROJECT_DIR:-.}` is therefore not the
66
+ * placeholder at all; it worked only where a POSIX shell happened to expand the variable, and on a
67
+ * host where Claude Code's own substitution is what fills the token in, it stays literal and the
68
+ * hook cannot be found. NOT REPRODUCED LIVE: there is no Windows host here, so the Windows half of
69
+ * this is documentation plus the reviewer's report, not a measurement of mine.
70
+ *
71
+ * MEASURED here (POSIX `sh`, 2026-09-06), which is the part that IS checkable: with the variable
72
+ * set the two forms are identical (`/tmp/x/p`); with it unset the exact token yields `/p` while the
73
+ * old form yielded `./p`. So on the only path this change can degrade — a hand-run command with no
74
+ * variable and no substitution — the failure is a loud "cannot find module", never a silent pass.
75
+ * The fallback that matters (finding the DECIDER) lives inside the body, where it can actually run.
76
+ */
77
+ export const CLAUDE_DESTRUCTIVE_HOOK_COMMAND = 'node "${CLAUDE_PROJECT_DIR}/' + CLAUDE_DESTRUCTIVE_HOOK_RELPATH + '"';
78
+ /** The PreToolUse matcher. Bash only — the decider skips every other tool without reading it. */
79
+ export const CLAUDE_DESTRUCTIVE_HOOK_MATCHER = '^Bash$';
80
+ /**
81
+ * The emitted `.claude/hooks/destructive-guard.cjs`.
82
+ *
83
+ * Thin by contract: read stdin, hand the payload to `decideDestructiveHook`, print, exit. Runtime
84
+ * failures of ours exit 0 with one loud line, but a deterministically missing decision module exits
85
+ * 2: setup cannot leave an armed-looking hook that allows every command until somebody builds it.
86
+ */
87
+ export function generateClaudeDestructiveHook(opts = {}) {
88
+ const installed = opts.installedDistDir === undefined ? harnessCoreDistDir() : opts.installedDistDir;
89
+ const bakedLine = installed === null
90
+ ? ' // No installed path was baked in (a body committed to a repository): project-local only.\n'
91
+ : ` candidates.push(${JSON.stringify(installed)} + '/destructive-guard-hook.js'); // the installation that emitted this file\n`;
92
+ return `#!/usr/bin/env node
93
+ // GENERATED by @dzhechkov/harness-core — dz-claude-hook-version: ${DZ_CLAUDE_HOOK_VERSION}
94
+ // ${CLAUDE_DESTRUCTIVE_HOOK_MARKER}
95
+ // Do not edit: this marker line is what tells dz the file is ITS OWN, so dz rewrites it on the next
96
+ // 'dz setup --target claude-code'. Delete the marker line to claim the file: dz then leaves it
97
+ // alone and only '--force' replaces it, after a timestamped backup.
98
+ //
99
+ // PreToolUse guard on Bash: a deletion by a LITERAL path into a protected store never runs.
100
+ // All of the policy — the three outcomes, the refusal text, the limits the guard must name — lives
101
+ // in @dzhechkov/harness-core (destructive-guard.js classifies, destructive-guard-hook.js decides).
102
+ // The same module decides for the Codex host, so both runtimes refuse the same commands in the
103
+ // same words.
104
+ 'use strict';
105
+
106
+ const path = require('node:path');
107
+ const { writeSync } = require('node:fs');
108
+ const { pathToFileURL } = require('node:url');
109
+
110
+ /**
111
+ * Load the decision module by PATH, project-local first, then the installation that emitted this
112
+ * file. 'import()' and never 'require()': harness-core is "type": "module", and require() of an ES
113
+ * module throws ERR_REQUIRE_ESM below Node 20.19 / 22.12 — which used to be caught and turned into
114
+ * a silent allow.
115
+ */
116
+ async function loadDecider() {
117
+ // CLAUDE_PROJECT_DIR when the host set it, else this file's own location. The env var is the
118
+ // host's own statement of where the project root is; __dirname is what still works when nobody
119
+ // said anything, including when this hook is run by hand.
120
+ const projectRoot = process.env.CLAUDE_PROJECT_DIR || path.resolve(__dirname, '..', '..');
121
+ // DZ_GUARD_TRUSTED_ONLY is set by 'dz setup' while it certifies this file. The probe SPAWNS the
122
+ // hook, so with project-local candidates first it would import — and execute the top level of —
123
+ // whatever a cloned repository committed at packages/@dzhechkov/harness-core/dist/, during setup
124
+ // and outside the host's hook-trust flow. The receipt must certify the TRUSTED installation, so
125
+ // for the probe the project's own copies are switched off. At RUNTIME they stay first: a project
126
+ // that ships its own harness-core is exactly who should decide there.
127
+ const trustedOnly = process.env.DZ_GUARD_TRUSTED_ONLY === '1';
128
+ const candidates = trustedOnly ? [] : [
129
+ path.join(projectRoot, 'node_modules', '@dzhechkov', 'harness-core', 'dist', 'destructive-guard-hook.js'),
130
+ path.join(projectRoot, 'packages', '@dzhechkov', 'harness-core', 'dist', 'destructive-guard-hook.js'),
131
+ ];
132
+ ${bakedLine} const failures = [];
133
+ for (const candidate of candidates) {
134
+ try {
135
+ const mod = await import(pathToFileURL(candidate).href);
136
+ const decide = mod.decideDestructiveHook || (mod.default && mod.default.decideDestructiveHook);
137
+ if (typeof decide === 'function') return { decide: decide, reason: null };
138
+ failures.push(candidate + ': загружен, но decideDestructiveHook не экспортирован');
139
+ } catch (err) {
140
+ const code = (err && err.code) || 'ERR_UNKNOWN';
141
+ failures.push(candidate + ': ' + code + ' ' + String((err && err.message) || err));
142
+ }
143
+ }
144
+ return { decide: null, reason: failures.join(' | ').replace(/\\s*\\n\\s*/g, ' ') };
145
+ }
146
+
147
+ let raw = '';
148
+ process.stdin.on('data', (c) => { raw += c; });
149
+ process.stdin.on('end', () => {
150
+ let payload = null;
151
+ try {
152
+ payload = JSON.parse(raw);
153
+ } catch (_) {
154
+ payload = null; // handed over as-is: the decider owns the "unreadable" wording too.
155
+ }
156
+ loadDecider().then(
157
+ (loaded) => onDecider(loaded, payload),
158
+ (err) => failOpen('страж опасных команд не смог загрузиться: ' + String((err && err.message) || err)),
159
+ );
160
+ });
161
+
162
+ /** One line, exit 0. Every failure of OURS ends here — loudly, and never as a refusal. */
163
+ function failOpen(what) {
164
+ process.stderr.write(
165
+ 'DZ-DESTRUCTIVE-WARN: ' + String(what).replace(/\\s*\\n\\s*/g, ' ') + ' — команда ПРОПУЩЕНА без проверки.\\n',
166
+ );
167
+ process.exit(0);
168
+ }
169
+
170
+ /** One line, exit 2. No decider means the guard installation is incomplete, so nothing may run. */
171
+ function failUnarmed(reason) {
172
+ const line =
173
+ 'DZ-DESTRUCTIVE: страж опасных команд не собран и не может проверить запрос — команда НЕ ВЫПОЛНЕНА. ' +
174
+ 'Причина: ' + String(reason).replace(/\\s*\\n\\s*/g, ' ') +
175
+ ' Починка: npm install -g @dzhechkov/harness-cli@latest, затем dz setup --target claude-code.\\n';
176
+ // Hook stderr is a pipe under the host and under spawnSync. An immediate process.exit can drop a
177
+ // buffered write entirely, so write this installation verdict synchronously before exiting.
178
+ writeSync(2, line);
179
+ process.exit(2);
180
+ }
181
+
182
+ function onDecider(loaded, payload) {
183
+ const decide = loaded.decide;
184
+ if (decide === null) {
185
+ failUnarmed(loaded.reason);
186
+ return;
187
+ }
188
+
189
+ let out = '';
190
+ let code = 0;
191
+ try {
192
+ const decision = decide(payload, 'claude');
193
+ if (!decision || typeof decision.stderr !== 'string') {
194
+ throw new TypeError('решение стража нечитаемо: ' + JSON.stringify(decision));
195
+ }
196
+ out = decision.stderr;
197
+ code = decision.exitCode === 2 ? 2 : 0; // 2 = block the call and show the reason.
198
+ } catch (err) {
199
+ failOpen('страж опасных команд упал (' + String((err && err.message) || err) + ')');
200
+ return;
201
+ }
202
+
203
+ if (out !== '') process.stderr.write(out);
204
+ process.exit(code);
205
+ }
206
+ `;
207
+ }
208
+ //# sourceMappingURL=claude-hooks-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-hooks-assets.js","sourceRoot":"","sources":["../src/claude-hooks-assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,uGAAuG;AACvG,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,oCAAoC,CAAC;AAEnF,gGAAgG;AAChG,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;AACvD,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,MAAM,+BAA+B,GAAG,qCAAqC,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAC1C,8BAA8B,GAAG,+BAA+B,GAAG,GAAG,CAAC;AAEzE,iGAAiG;AACjG,MAAM,CAAC,MAAM,+BAA+B,GAAG,QAAQ,CAAC;AAWxD;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,OAA+B,EAAE;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;IACrG,MAAM,SAAS,GACb,SAAS,KAAK,IAAI;QAChB,CAAC,CAAC,+FAA+F;QACjG,CAAC,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,gFAAgF,CAAC;IAErI,OAAO;oEAC2D,sBAAsB;KACrF,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCjC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0EV,CAAC;AACF,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Чистая комната: проверить пакет так, как его увидит НОВЫЙ пользователь.
3
+ *
4
+ * ЗАЧЕМ. Разработчик забыл включить файл в поставку — на его машине всё работает, потому что файл
5
+ * лежит рядом в репозитории; у покупателя коробка приходит без детали. Класс называется
6
+ * `files[]`/install-layout, и локальный прогон его не ловит ПО ПОСТРОЕНИЮ: он видит рабочее дерево.
7
+ *
8
+ * ЧЕСТНАЯ ГРАНИЦА, названная сразу и повторённая в вердикте: «в чистой комнате завелось» НЕ РАВНО
9
+ * «Claude Code пакет увидел». ИЗМЕРЕНО ранее: health-advisor 1.2.0 был зелёным в чистой комнате на
10
+ * пакете, чьи навыки не регистрировались вовсе. Это ДОПОЛНЕНИЕ к живой пробе регистрации, а не её
11
+ * замена.
12
+ *
13
+ * ЧИСТАЯ ПОЛОВИНА. Здесь нет ни Docker, ни файловой системы: `planCleanRoom` решает, ЧТО осмысленно
14
+ * запустить для этого манифеста, а `cleanRoomVerdict` превращает НАБЛЮДЕНИЕ в вердикт. Обе половины
15
+ * проверяются без контейнера; запускает их скрипт `scripts/clean-room-smoke.mjs`.
16
+ */
17
+ /** Что и почему запускать в контейнере. `kind: 'refuse'` — смотреть нечего, и это НЕ успех. */
18
+ export type CleanRoomPlan = {
19
+ readonly kind: 'bin';
20
+ /** Имя исполняемого файла из `bin`, которое будет вызвано с `--help`. */
21
+ readonly binName: string;
22
+ readonly argv: readonly string[];
23
+ readonly why: string;
24
+ } | {
25
+ readonly kind: 'import';
26
+ /** Имя пакета, которое будет импортировано из установленной копии. */
27
+ readonly packageName: string;
28
+ readonly why: string;
29
+ } | {
30
+ readonly kind: 'files-only';
31
+ /** Файл из поставки, чьё присутствие проверяется после установки. */
32
+ readonly probeFile: string;
33
+ readonly why: string;
34
+ } | {
35
+ readonly kind: 'refuse';
36
+ readonly reason: string;
37
+ };
38
+ interface ManifestLike {
39
+ readonly name?: unknown;
40
+ readonly bin?: unknown;
41
+ readonly main?: unknown;
42
+ readonly exports?: unknown;
43
+ readonly files?: unknown;
44
+ readonly private?: unknown;
45
+ }
46
+ /**
47
+ * Выбрать пробу по манифесту — от самой сильной к самой слабой.
48
+ *
49
+ * ПОРЯДОК НЕ ПРОИЗВОЛЕН. Запуск бинаря проверяет и установку, и разрешение зависимостей, и то,
50
+ * что точка входа физически приехала. Импорт проверяет первые две. Присутствие файла — только
51
+ * состав поставки. Слабейшая проба ВЫБИРАЕТСЯ ТОЛЬКО тогда, когда сильнее нечего запустить, и её
52
+ * слабость названа в тексте `why`, чтобы читатель отчёта не принял её за полную проверку.
53
+ */
54
+ export declare function planCleanRoom(manifest: ManifestLike): CleanRoomPlan;
55
+ /** Что наблюдалось в контейнере. `exitCode: null` — процесс не завершился сам (убит, срок). */
56
+ export interface CleanRoomObservation {
57
+ readonly plan: CleanRoomPlan;
58
+ readonly installOk: boolean;
59
+ readonly installOutput: string;
60
+ readonly exitCode: number | null;
61
+ readonly stdout: string;
62
+ readonly stderr: string;
63
+ }
64
+ export type CleanRoomVerdict = {
65
+ readonly ok: true;
66
+ readonly detail: string;
67
+ readonly limit: string;
68
+ } | {
69
+ readonly ok: false;
70
+ readonly detail: string;
71
+ };
72
+ /** Оговорка, которую вердикт несёт ВСЕГДА: зелень чистой комнаты ≠ регистрация у клиента. */
73
+ export declare const CLEAN_ROOM_LIMIT: string;
74
+ /**
75
+ * Превратить наблюдение в вердикт.
76
+ *
77
+ * УСПЕХ НЕ ВЫВОДИТСЯ ИЗ ТИШИНЫ: отсутствие вывода при нулевом коде — не доказательство запуска, и
78
+ * для пробы бинаря требуется НЕПУСТОЙ вывод. Установка, не завершившаяся успехом, делает любой
79
+ * последующий результат бессмысленным, и это говорится первой строкой.
80
+ */
81
+ export declare function cleanRoomVerdict(o: CleanRoomObservation): CleanRoomVerdict;
82
+ export {};
83
+ //# sourceMappingURL=clean-room-smoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean-room-smoke.d.ts","sourceRoot":"","sources":["../src/clean-room-smoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,+FAA+F;AAC/F,MAAM,MAAM,aAAa,GACrB;IACE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,UAAU,YAAY;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAsCnE;AA8BD,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,QAEoE,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,oBAAoB,GAAG,gBAAgB,CAyB1E"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Чистая комната: проверить пакет так, как его увидит НОВЫЙ пользователь.
3
+ *
4
+ * ЗАЧЕМ. Разработчик забыл включить файл в поставку — на его машине всё работает, потому что файл
5
+ * лежит рядом в репозитории; у покупателя коробка приходит без детали. Класс называется
6
+ * `files[]`/install-layout, и локальный прогон его не ловит ПО ПОСТРОЕНИЮ: он видит рабочее дерево.
7
+ *
8
+ * ЧЕСТНАЯ ГРАНИЦА, названная сразу и повторённая в вердикте: «в чистой комнате завелось» НЕ РАВНО
9
+ * «Claude Code пакет увидел». ИЗМЕРЕНО ранее: health-advisor 1.2.0 был зелёным в чистой комнате на
10
+ * пакете, чьи навыки не регистрировались вовсе. Это ДОПОЛНЕНИЕ к живой пробе регистрации, а не её
11
+ * замена.
12
+ *
13
+ * ЧИСТАЯ ПОЛОВИНА. Здесь нет ни Docker, ни файловой системы: `planCleanRoom` решает, ЧТО осмысленно
14
+ * запустить для этого манифеста, а `cleanRoomVerdict` превращает НАБЛЮДЕНИЕ в вердикт. Обе половины
15
+ * проверяются без контейнера; запускает их скрипт `scripts/clean-room-smoke.mjs`.
16
+ */
17
+ /**
18
+ * Выбрать пробу по манифесту — от самой сильной к самой слабой.
19
+ *
20
+ * ПОРЯДОК НЕ ПРОИЗВОЛЕН. Запуск бинаря проверяет и установку, и разрешение зависимостей, и то,
21
+ * что точка входа физически приехала. Импорт проверяет первые две. Присутствие файла — только
22
+ * состав поставки. Слабейшая проба ВЫБИРАЕТСЯ ТОЛЬКО тогда, когда сильнее нечего запустить, и её
23
+ * слабость названа в тексте `why`, чтобы читатель отчёта не принял её за полную проверку.
24
+ */
25
+ export function planCleanRoom(manifest) {
26
+ if (manifest.private === true) {
27
+ return { kind: 'refuse', reason: 'пакет приватный — он не публикуется, и проверять поставку не для кого' };
28
+ }
29
+ const name = typeof manifest.name === 'string' && manifest.name.trim() !== '' ? manifest.name.trim() : null;
30
+ if (name === null) {
31
+ return { kind: 'refuse', reason: 'манифест не называет пакет — установить его в чистой комнате нельзя' };
32
+ }
33
+ const binName = firstBinName(manifest.bin, name);
34
+ if (binName !== null) {
35
+ return {
36
+ kind: 'bin', binName, argv: ['--help'],
37
+ why: 'запуск исполняемого файла проверяет установку, разрешение зависимостей И то, что точка входа приехала в поставке',
38
+ };
39
+ }
40
+ // ИМПОРТ ОСМЫСЛЕН, ТОЛЬКО ЕСЛИ ТОЧКА ВХОДА — ЗАГРУЖАЕМЫЙ МОДУЛЬ. ИЗМЕРЕНО 2026-09-04:
41
+ // `@dzhechkov/keysarium-core` объявляет `main: "index.md"`, и импорт падает с «Unknown file
42
+ // extension ".md"» — это верное наблюдение О МАНИФЕСТЕ, но негодная ПРОБА поставки: пакет
43
+ // документационный, и его состав проверяется присутствием файла. Обвинять поставку в том, что
44
+ // объявлено в манифесте, — путать два разных дефекта.
45
+ if (isLoadableEntry(manifest.main) || manifest.exports !== undefined) {
46
+ return {
47
+ kind: 'import', packageName: name,
48
+ why: 'импорт проверяет установку и разрешение зависимостей; ЧТО пакет делает — не проверяется',
49
+ };
50
+ }
51
+ const probe = firstFile(manifest.files);
52
+ if (probe !== null) {
53
+ return {
54
+ kind: 'files-only', probeFile: probe,
55
+ why: 'у пакета нет ни исполняемого файла, ни точки входа — проверяется ТОЛЬКО то, что объявленный файл приехал; это самая слабая из проб',
56
+ };
57
+ }
58
+ return { kind: 'refuse', reason: 'манифест не объявляет ни bin, ни точки входа, ни files — запускать в чистой комнате нечего' };
59
+ }
60
+ /** Загружаемая ли это точка входа: расширение, которое Node умеет исполнять как модуль. */
61
+ function isLoadableEntry(main) {
62
+ return typeof main === 'string' && /\.(?:js|mjs|cjs|node)$/i.test(main.trim());
63
+ }
64
+ /** Первое имя из `bin`. Строка — это имя самого пакета (без области), объект — первый ключ. */
65
+ function firstBinName(bin, packageName) {
66
+ if (typeof bin === 'string' && bin.trim() !== '') {
67
+ const base = packageName.startsWith('@') ? packageName.split('/')[1] ?? packageName : packageName;
68
+ return base;
69
+ }
70
+ if (typeof bin === 'object' && bin !== null && !Array.isArray(bin)) {
71
+ for (const key of Object.keys(bin)) {
72
+ if (key.trim() !== '')
73
+ return key;
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ /** Первый ОБЫЧНЫЙ путь из `files` — образцы (`*`) проверять присутствием нельзя. */
79
+ function firstFile(files) {
80
+ if (!Array.isArray(files))
81
+ return null;
82
+ for (const f of files) {
83
+ if (typeof f === 'string' && f.trim() !== '' && !f.includes('*'))
84
+ return f.replace(/\/+$/, '');
85
+ }
86
+ return null;
87
+ }
88
+ /** Оговорка, которую вердикт несёт ВСЕГДА: зелень чистой комнаты ≠ регистрация у клиента. */
89
+ export const CLEAN_ROOM_LIMIT = 'чистая комната доказывает, что поставка УСТАНАВЛИВАЕТСЯ и запускается; она НЕ доказывает, '
90
+ + 'что Claude Code увидел навыки пакета — для этого живая проба регистрации (dz skills-verify)';
91
+ /**
92
+ * Превратить наблюдение в вердикт.
93
+ *
94
+ * УСПЕХ НЕ ВЫВОДИТСЯ ИЗ ТИШИНЫ: отсутствие вывода при нулевом коде — не доказательство запуска, и
95
+ * для пробы бинаря требуется НЕПУСТОЙ вывод. Установка, не завершившаяся успехом, делает любой
96
+ * последующий результат бессмысленным, и это говорится первой строкой.
97
+ */
98
+ export function cleanRoomVerdict(o) {
99
+ if (o.plan.kind === 'refuse') {
100
+ return { ok: false, detail: `проба не выбрана: ${o.plan.reason}` };
101
+ }
102
+ if (!o.installOk) {
103
+ // Провалившаяся установка делает любой последующий результат бессмысленным — и это говорится
104
+ // ПЕРВОЙ строкой, чтобы читатель не искал причину в проверке.
105
+ return { ok: false, detail: `установка из тарбола НЕ прошла — всё остальное о ней ничего не говорит: ${firstLine(o.installOutput)}` };
106
+ }
107
+ if (o.exitCode === null) {
108
+ return { ok: false, detail: 'проба не завершилась сама (убита или истёк срок) — исход НЕ УСТАНОВЛЕН, и это не успех' };
109
+ }
110
+ if (o.exitCode !== 0) {
111
+ return { ok: false, detail: `проба вышла с кодом ${o.exitCode}: ${firstLine(o.stderr) || firstLine(o.stdout) || '(вывода нет)'}` };
112
+ }
113
+ if (o.plan.kind === 'bin' && o.stdout.trim() === '' && o.stderr.trim() === '') {
114
+ // Ноль и тишина — это не «сработало». Ровно так выглядит бинарь, чья точка входа не приехала,
115
+ // если оболочка проглотила ошибку: успех, выведенный из тишины, и есть тот дефект, который
116
+ // чистая комната обязана ловить.
117
+ return { ok: false, detail: 'исполняемый файл вышел с нулём и НИЧЕГО не написал — тишина не доказывает запуск' };
118
+ }
119
+ const what = o.plan.kind === 'bin' ? `\`${o.plan.binName} ${o.plan.argv.join(' ')}\``
120
+ : o.plan.kind === 'import' ? `импорт ${o.plan.packageName}`
121
+ : `присутствие ${o.plan.probeFile}`;
122
+ return { ok: true, detail: `установка прошла, ${what} — успешно`, limit: CLEAN_ROOM_LIMIT };
123
+ }
124
+ /**
125
+ * Первая строка, которая ОБЪЯСНЯЕТ отказ, а не первая непустая.
126
+ *
127
+ * ИЗМЕРЕНО 2026-09-04 на живом прогоне: у сломанной поставки первой непустой строкой оказалась
128
+ * `node:fs:560` — кадр стека. Такой текст в вердикте отправляет читателя в файл среды выполнения
129
+ * вместо причины (`ENOENT … templates/…`). Поэтому сначала ищется строка, ПОХОЖАЯ на сообщение об
130
+ * ошибке, и только если такой нет — берётся первая непустая.
131
+ */
132
+ function firstLine(text) {
133
+ const lines = String(text ?? '').split('\n').map((l) => l.trim()).filter((l) => l !== '');
134
+ const explains = lines.find((l) => /\b(?:Error|ENOENT|EACCES|ERR_[A-Z_]+|Cannot find|not found|npm ERR!)\b/i.test(l));
135
+ const chosen = explains ?? lines[0];
136
+ return chosen === undefined ? '' : chosen.slice(0, 200);
137
+ }
138
+ //# sourceMappingURL=clean-room-smoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean-room-smoke.js","sourceRoot":"","sources":["../src/clean-room-smoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAqCH;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,QAAsB;IAClD,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,uEAAuE,EAAE,CAAC;IAC7G,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5G,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,qEAAqE,EAAE,CAAC;IAC3G,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO;YACL,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC;YACtC,GAAG,EAAE,kHAAkH;SACxH,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,4FAA4F;IAC5F,0FAA0F;IAC1F,8FAA8F;IAC9F,sDAAsD;IACtD,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACrE,OAAO;YACL,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI;YACjC,GAAG,EAAE,yFAAyF;SAC/F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO;YACL,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK;YACpC,GAAG,EAAE,oIAAoI;SAC1I,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,4FAA4F,EAAE,CAAC;AAClI,CAAC;AAED,2FAA2F;AAC3F,SAAS,eAAe,CAAC,IAAa;IACpC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,+FAA+F;AAC/F,SAAS,YAAY,CAAC,GAAY,EAAE,WAAmB;IACrD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;QAClG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,OAAO,GAAG,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oFAAoF;AACpF,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD,6FAA6F;AAC7F,MAAM,CAAC,MAAM,gBAAgB,GAC3B,4FAA4F;MAC1F,6FAA6F,CAAC;AAElG;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAuB;IACtD,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QACjB,6FAA6F;QAC7F,8DAA8D;QAC9D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,2EAA2E,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;IACxI,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wFAAwF,EAAE,CAAC;IACzH,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,cAAc,EAAE,EAAE,CAAC;IACrI,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9E,8FAA8F;QAC9F,2FAA2F;QAC3F,iCAAiC;QACjC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kFAAkF,EAAE,CAAC;IACnH,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;QACnF,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;YACzD,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,IAAI,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;AAC9F,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1F,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,yEAAyE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtH,MAAM,MAAM,GAAG,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cmd-usage.d.ts","sourceRoot":"","sources":["../src/cmd-usage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cmd-usage.d.ts","sourceRoot":"","sources":["../src/cmd-usage.ts"],"names":[],"mappings":"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"}
package/dist/cmd-usage.js CHANGED
@@ -26,17 +26,47 @@ const DAY_MS = 86_400_000;
26
26
  export function resolveCmdUsageRoot(startDir) {
27
27
  try {
28
28
  let dir = resolve(startDir);
29
+ let nearestStore = null;
29
30
  for (let level = 0; level < 64; level += 1) {
30
- try {
31
- if (statSync(join(dir, '.dz')).isDirectory())
32
- return dir;
31
+ // Ближайший `.dz` запоминается, но НЕ возвращается сразу — см. объяснение ниже.
32
+ if (nearestStore === null) {
33
+ try {
34
+ if (statSync(join(dir, '.dz')).isDirectory())
35
+ nearestStore = dir;
36
+ }
37
+ catch { /* not here; keep walking */ }
33
38
  }
34
- catch {
35
- /* not here; keep walking */
39
+ // ГРАНИЦА РЕПОЗИТОРИЯ ВЫИГРЫВАЕТ У БЛИЖАЙШЕГО СКЛАДА, и вот почему.
40
+ //
41
+ // ИЗМЕРЕНО 2026-09-03: прогон `dz`, чей рабочий каталог оказался внутри пакета, создал там
42
+ // `.dz/` — и с того момента поиск останавливался на нём. Итог: 1149 записей об использовании
43
+ // команд уехали в склад внутри пакета вместо корневого, где их 17 265. Журнал разошёлся
44
+ // надвое молча, и обнаружил это только тест, требовавший корень монорепо.
45
+ //
46
+ // Тот же класс, что чинился в p-replicator неделей раньше, но зеркально: там поиск шёл ВЫШЕ
47
+ // границы репозитория, здесь останавливается НИЖЕ неё. Общее правило одно — у поиска корня
48
+ // должна быть НАЗВАННАЯ граница, а не первое попавшееся совпадение.
49
+ const atBoundary = (() => {
50
+ for (const marker of ['.git', 'pnpm-workspace.yaml']) {
51
+ try {
52
+ statSync(join(dir, marker));
53
+ return true;
54
+ }
55
+ catch { /* keep checking */ }
56
+ }
57
+ return false;
58
+ })();
59
+ if (atBoundary) {
60
+ try {
61
+ if (statSync(join(dir, '.dz')).isDirectory())
62
+ return dir;
63
+ }
64
+ catch { /* граница без склада — отдаём ближайший найденный */ }
65
+ return nearestStore ?? startDir;
36
66
  }
37
67
  const parent = dirname(dir);
38
68
  if (parent === dir)
39
- return startDir;
69
+ return nearestStore ?? startDir;
40
70
  dir = parent;
41
71
  }
42
72
  }