harnery 0.5.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 (68) 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/cookies.js +1 -1
  10. package/dist/commands/decision.d.ts +4 -0
  11. package/dist/commands/decision.d.ts.map +1 -0
  12. package/dist/commands/decision.js +354 -0
  13. package/dist/commands/docs.d.ts.map +1 -1
  14. package/dist/commands/docs.js +5 -1
  15. package/dist/commands/fetch.js +1 -1
  16. package/dist/core/agents/events/consume.d.ts +25 -2
  17. package/dist/core/agents/events/consume.d.ts.map +1 -1
  18. package/dist/core/agents/events/consume.js +55 -7
  19. package/dist/core/agents/events/emit.d.ts +2 -1
  20. package/dist/core/agents/events/emit.d.ts.map +1 -1
  21. package/dist/core/agents/events/emit.js +2 -1
  22. package/dist/core/agents/state/scratch.d.ts +1 -1
  23. package/dist/core/agents/state/scratch.js +2 -2
  24. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  25. package/dist/core/hooks/effects/index.js +2 -1
  26. package/dist/lib/agent-browser/client.js +1 -1
  27. package/dist/lib/browser/client.d.ts +14 -0
  28. package/dist/lib/browser/client.d.ts.map +1 -1
  29. package/dist/lib/browser/client.js +20 -0
  30. package/dist/lib/browser/index.d.ts +1 -0
  31. package/dist/lib/browser/index.d.ts.map +1 -1
  32. package/dist/lib/browser/runts.d.ts +44 -0
  33. package/dist/lib/browser/runts.d.ts.map +1 -0
  34. package/dist/lib/browser/runts.js +193 -0
  35. package/dist/lib/completion/walk.js +1 -1
  36. package/dist/lib/cookies/client.d.ts +1 -1
  37. package/dist/lib/cookies/client.d.ts.map +1 -1
  38. package/dist/lib/cookies/client.js +1 -1
  39. package/dist/lib/decision/index.d.ts +212 -0
  40. package/dist/lib/decision/index.d.ts.map +1 -0
  41. package/dist/lib/decision/index.js +523 -0
  42. package/dist/lib/docs-lint.d.ts +1 -0
  43. package/dist/lib/docs-lint.d.ts.map +1 -1
  44. package/dist/lib/docs-lint.js +49 -0
  45. package/dist/lib/tunnel/gate.js +1 -1
  46. package/package.json +3 -1
  47. package/src/commander.ts +12 -0
  48. package/src/commands/agents.ts +47 -26
  49. package/src/commands/browse-ai.ts +1 -1
  50. package/src/commands/browse.ts +63 -8
  51. package/src/commands/cookies.ts +1 -1
  52. package/src/commands/decision.ts +438 -0
  53. package/src/commands/docs.ts +5 -1
  54. package/src/commands/fetch.ts +1 -1
  55. package/src/core/agents/events/consume.ts +65 -7
  56. package/src/core/agents/events/emit.ts +2 -1
  57. package/src/core/agents/state/scratch.ts +2 -2
  58. package/src/core/config.ts +1 -1
  59. package/src/core/hooks/effects/index.ts +2 -1
  60. package/src/lib/agent-browser/client.ts +1 -1
  61. package/src/lib/browser/client.ts +28 -0
  62. package/src/lib/browser/index.ts +4 -0
  63. package/src/lib/browser/runts.ts +218 -0
  64. package/src/lib/completion/walk.ts +1 -1
  65. package/src/lib/cookies/client.ts +2 -2
  66. package/src/lib/decision/index.ts +685 -0
  67. package/src/lib/docs-lint.ts +44 -0
  68. 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[] = [];
@@ -402,6 +445,7 @@ export async function runLint(opts: LintOpts): Promise<Violation[]> {
402
445
  for (const { name, path, isSubmodule } of repos) {
403
446
  violations.push(...checkEntryTier(name, path, isSubmodule));
404
447
  violations.push(...checkRootAllowlist(name, path));
448
+ violations.push(...checkDocsRootAllowlist(name, path));
405
449
 
406
450
  const files = await findMarkdownFiles(path);
407
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