harnery 0.4.0 → 0.6.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.
Files changed (100) hide show
  1. package/dist/commander.d.ts +10 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +2 -0
  4. package/dist/commands/agents.d.ts.map +1 -1
  5. package/dist/commands/agents.js +43 -29
  6. package/dist/commands/browse-ai.js +1 -1
  7. package/dist/commands/browse.d.ts.map +1 -1
  8. package/dist/commands/browse.js +41 -9
  9. package/dist/commands/completion.d.ts.map +1 -1
  10. package/dist/commands/completion.js +48 -10
  11. package/dist/commands/cookies.js +1 -1
  12. package/dist/commands/decision.d.ts +4 -0
  13. package/dist/commands/decision.d.ts.map +1 -0
  14. package/dist/commands/decision.js +354 -0
  15. package/dist/commands/docs.d.ts.map +1 -1
  16. package/dist/commands/docs.js +5 -1
  17. package/dist/commands/fetch.js +1 -1
  18. package/dist/core/agents/events/consume.d.ts +25 -2
  19. package/dist/core/agents/events/consume.d.ts.map +1 -1
  20. package/dist/core/agents/events/consume.js +55 -7
  21. package/dist/core/agents/events/emit.d.ts +2 -1
  22. package/dist/core/agents/events/emit.d.ts.map +1 -1
  23. package/dist/core/agents/events/emit.js +2 -1
  24. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  25. package/dist/core/agents/rules/claim-conflict.js +10 -2
  26. package/dist/core/agents/state/scratch.d.ts +1 -1
  27. package/dist/core/agents/state/scratch.js +2 -2
  28. package/dist/core/hooks/cli.js +4 -10
  29. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  30. package/dist/core/hooks/effects/index.js +2 -1
  31. package/dist/core/hooks/guard-path.d.ts +29 -0
  32. package/dist/core/hooks/guard-path.d.ts.map +1 -0
  33. package/dist/core/hooks/guard-path.js +38 -0
  34. package/dist/lib/agent-browser/client.js +1 -1
  35. package/dist/lib/browser/client.d.ts +14 -0
  36. package/dist/lib/browser/client.d.ts.map +1 -1
  37. package/dist/lib/browser/client.js +20 -0
  38. package/dist/lib/browser/index.d.ts +1 -0
  39. package/dist/lib/browser/index.d.ts.map +1 -1
  40. package/dist/lib/browser/runts.d.ts +44 -0
  41. package/dist/lib/browser/runts.d.ts.map +1 -0
  42. package/dist/lib/browser/runts.js +193 -0
  43. package/dist/lib/completion/bash.d.ts +15 -0
  44. package/dist/lib/completion/bash.d.ts.map +1 -1
  45. package/dist/lib/completion/bash.js +35 -0
  46. package/dist/lib/completion/fish.d.ts +10 -0
  47. package/dist/lib/completion/fish.d.ts.map +1 -1
  48. package/dist/lib/completion/fish.js +21 -0
  49. package/dist/lib/completion/index.d.ts +4 -3
  50. package/dist/lib/completion/index.d.ts.map +1 -1
  51. package/dist/lib/completion/index.js +4 -3
  52. package/dist/lib/completion/resolve.d.ts +52 -0
  53. package/dist/lib/completion/resolve.d.ts.map +1 -0
  54. package/dist/lib/completion/resolve.js +171 -0
  55. package/dist/lib/completion/walk.js +1 -1
  56. package/dist/lib/completion/zsh.d.ts +8 -0
  57. package/dist/lib/completion/zsh.d.ts.map +1 -1
  58. package/dist/lib/completion/zsh.js +33 -0
  59. package/dist/lib/cookies/client.d.ts +1 -1
  60. package/dist/lib/cookies/client.d.ts.map +1 -1
  61. package/dist/lib/cookies/client.js +1 -1
  62. package/dist/lib/decision/index.d.ts +212 -0
  63. package/dist/lib/decision/index.d.ts.map +1 -0
  64. package/dist/lib/decision/index.js +523 -0
  65. package/dist/lib/docs-lint.d.ts +1 -0
  66. package/dist/lib/docs-lint.d.ts.map +1 -1
  67. package/dist/lib/docs-lint.js +55 -0
  68. package/dist/lib/tunnel/gate.js +1 -1
  69. package/package.json +3 -1
  70. package/src/commander.ts +12 -0
  71. package/src/commands/agents.ts +47 -26
  72. package/src/commands/browse-ai.ts +1 -1
  73. package/src/commands/browse.ts +63 -8
  74. package/src/commands/completion.ts +62 -9
  75. package/src/commands/cookies.ts +1 -1
  76. package/src/commands/decision.ts +438 -0
  77. package/src/commands/docs.ts +5 -1
  78. package/src/commands/fetch.ts +1 -1
  79. package/src/core/agents/events/consume.ts +65 -7
  80. package/src/core/agents/events/emit.ts +2 -1
  81. package/src/core/agents/rules/claim-conflict.ts +10 -2
  82. package/src/core/agents/state/scratch.ts +2 -2
  83. package/src/core/config.ts +1 -1
  84. package/src/core/hooks/cli.ts +4 -8
  85. package/src/core/hooks/effects/index.ts +2 -1
  86. package/src/core/hooks/guard-path.ts +34 -0
  87. package/src/lib/agent-browser/client.ts +1 -1
  88. package/src/lib/browser/client.ts +28 -0
  89. package/src/lib/browser/index.ts +4 -0
  90. package/src/lib/browser/runts.ts +218 -0
  91. package/src/lib/completion/bash.ts +36 -0
  92. package/src/lib/completion/fish.ts +22 -0
  93. package/src/lib/completion/index.ts +12 -3
  94. package/src/lib/completion/resolve.ts +210 -0
  95. package/src/lib/completion/walk.ts +1 -1
  96. package/src/lib/completion/zsh.ts +34 -0
  97. package/src/lib/cookies/client.ts +2 -2
  98. package/src/lib/decision/index.ts +685 -0
  99. package/src/lib/docs-lint.ts +49 -0
  100. package/src/lib/tunnel/gate.ts +1 -1
@@ -9,15 +9,18 @@ import { sh } from "./exec.ts";
9
9
  let REPO_ROOT = "";
10
10
  let SUBMODULES: readonly string[] = [];
11
11
  let EXTRA_EXCLUDED_PREFIXES: readonly string[] = [];
12
+ let DOCS_ROOT_ALLOWLIST: readonly string[] = [];
12
13
 
13
14
  export function initDocsContext(opts: {
14
15
  repoRoot: string;
15
16
  submodules: readonly string[];
16
17
  extraExcludedPrefixes?: readonly string[];
18
+ docsRootAllowlist?: readonly string[];
17
19
  }): void {
18
20
  REPO_ROOT = opts.repoRoot;
19
21
  SUBMODULES = opts.submodules;
20
22
  EXTRA_EXCLUDED_PREFIXES = opts.extraExcludedPrefixes ?? [];
23
+ DOCS_ROOT_ALLOWLIST = opts.docsRootAllowlist ?? [];
21
24
  }
22
25
 
23
26
  function submodulePath(name: string): string {
@@ -239,6 +242,46 @@ function checkRootAllowlist(repoName: string, repoPath: string): Violation[] {
239
242
  return violations;
240
243
  }
241
244
 
245
+ /**
246
+ * The host project's `docs/` root is an entry tier: only allowlisted files may
247
+ * sit loose there; topic docs belong in `docs/<topic>/` subdirs. Config-gated —
248
+ * a no-op unless the host supplies `docsRootAllowlist`. Parent-repo only:
249
+ * submodule `docs/` roots have their own entry tiers, not this one.
250
+ */
251
+ function checkDocsRootAllowlist(repoName: string, repoPath: string): Violation[] {
252
+ const violations: Violation[] = [];
253
+ if (DOCS_ROOT_ALLOWLIST.length === 0) return violations; // opt-in
254
+ if (repoName !== "(root)") return violations; // parent repo only
255
+ const allow = new Set(DOCS_ROOT_ALLOWLIST);
256
+ const docsDir = join(repoPath, "docs");
257
+ let entries: string[];
258
+ try {
259
+ entries = readdirSync(docsDir);
260
+ } catch {
261
+ return violations; // no docs/ dir — nothing to check
262
+ }
263
+ for (const entry of entries) {
264
+ // Subdirs are the intended home for topic docs; only loose files matter.
265
+ let isFile: boolean;
266
+ try {
267
+ isFile = statSync(join(docsDir, entry)).isFile();
268
+ } catch {
269
+ continue;
270
+ }
271
+ if (!isFile) continue;
272
+ if (!(entry.endsWith(".md") || entry.endsWith(".json"))) continue;
273
+ if (allow.has(entry)) continue;
274
+ violations.push({
275
+ severity: "error",
276
+ repo: repoName,
277
+ path: join("docs", entry),
278
+ rule: "docs-root-file",
279
+ message: `${entry} is not allowed loose at docs/ root — move it into a docs/<topic>/ subdir (or add it to context.docsRootAllowlist if it's a genuine entry-tier doc)`,
280
+ });
281
+ }
282
+ return violations;
283
+ }
284
+
242
285
  /** No SCREAMING_SNAKE_CASE filenames anywhere */
243
286
  function checkNamingConvention(repoName: string, _repoPath: string, files: string[]): Violation[] {
244
287
  const violations: Violation[] = [];
@@ -246,6 +289,11 @@ function checkNamingConvention(repoName: string, _repoPath: string, files: strin
246
289
  const name = basename(rel);
247
290
  // Allowlisted names
248
291
  if (ROOT_FILE_ALLOWLIST.has(name)) continue;
292
+ // Leading-underscore files are deliberate templates / meta files
293
+ // (e.g. _template.md), not content. The underscore is a convention
294
+ // marking "copy me, don't read me as a real doc", so exempt them
295
+ // from naming discipline rather than forcing kebab-case.
296
+ if (name.startsWith("_")) continue;
249
297
  // Dated files (audits/issues)
250
298
  if (DATED_FILE_PATTERN.test(name)) continue;
251
299
  // Changelogs
@@ -397,6 +445,7 @@ export async function runLint(opts: LintOpts): Promise<Violation[]> {
397
445
  for (const { name, path, isSubmodule } of repos) {
398
446
  violations.push(...checkEntryTier(name, path, isSubmodule));
399
447
  violations.push(...checkRootAllowlist(name, path));
448
+ violations.push(...checkDocsRootAllowlist(name, path));
400
449
 
401
450
  const files = await findMarkdownFiles(path);
402
451
  violations.push(...checkNamingConvention(name, path, files));
@@ -109,5 +109,5 @@ const server = Bun.serve<WsData, never>({
109
109
  // This worker runs detached via `bun run gate.ts`, outside the CLI command
110
110
  // framework, so no AsyncLocalStorage context is available. stdout/stderr is
111
111
  // captured into .cache/tunnel/gate.log by the spawning command.
112
- console.log(`bp-tunnel-gate :${server.port} -> ${UPSTREAM_HTTP} (Host: ${VHOST})`); // lint-ok-emission: detached worker, see file note above
112
+ console.log(`harn-tunnel-gate :${server.port} -> ${UPSTREAM_HTTP} (Host: ${VHOST})`); // lint-ok-emission: detached worker, see file note above
113
113
  console.log(`allow: ${[...ALLOW].join(", ") || "(empty, denies all)"}`); // lint-ok-emission: detached worker, see file note above