@kirrosh/zond 0.21.0 → 0.22.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 (52) hide show
  1. package/CHANGELOG.md +110 -3
  2. package/README.md +26 -15
  3. package/package.json +10 -6
  4. package/src/cli/commands/ci-init.ts +12 -6
  5. package/src/cli/commands/completions.ts +176 -0
  6. package/src/cli/commands/db.ts +2 -1
  7. package/src/cli/commands/generate.ts +0 -1
  8. package/src/cli/commands/init/agents-md.ts +61 -0
  9. package/src/cli/commands/init/bootstrap.ts +79 -0
  10. package/src/cli/commands/init/skills.ts +45 -0
  11. package/src/cli/commands/init/templates/agents.md +73 -0
  12. package/src/cli/commands/init/templates/markdown.d.ts +4 -0
  13. package/src/cli/commands/init/templates/skills/scenarios.md +97 -0
  14. package/src/cli/commands/init/templates/skills/zond.md +184 -0
  15. package/src/cli/commands/init/templates/zond-config.yml +15 -0
  16. package/src/cli/commands/init.ts +124 -31
  17. package/src/cli/commands/probe-methods.ts +108 -0
  18. package/src/cli/commands/probe-validation.ts +124 -0
  19. package/src/cli/commands/run.ts +99 -10
  20. package/src/cli/commands/serve.ts +52 -19
  21. package/src/cli/commands/sync.ts +0 -1
  22. package/src/cli/commands/update.ts +1 -1
  23. package/src/cli/commands/use.ts +57 -0
  24. package/src/cli/index.ts +21 -609
  25. package/src/cli/program.ts +655 -0
  26. package/src/cli/version.ts +3 -0
  27. package/src/core/context/current.ts +35 -0
  28. package/src/core/diagnostics/db-analysis.ts +11 -2
  29. package/src/core/diagnostics/render-md.ts +112 -0
  30. package/src/core/generator/chunker.ts +14 -2
  31. package/src/core/generator/data-factory.ts +50 -19
  32. package/src/core/generator/guide-builder.ts +1 -1
  33. package/src/core/generator/openapi-reader.ts +18 -0
  34. package/src/core/generator/serializer.ts +11 -2
  35. package/src/core/generator/suite-generator.ts +106 -7
  36. package/src/core/meta/types.ts +0 -2
  37. package/src/core/parser/schema.ts +3 -1
  38. package/src/core/parser/types.ts +10 -1
  39. package/src/core/parser/variables.ts +90 -2
  40. package/src/core/parser/yaml-parser.ts +50 -1
  41. package/src/core/probe/method-probe.ts +197 -0
  42. package/src/core/probe/negative-probe.ts +657 -0
  43. package/src/core/reporter/console.ts +29 -3
  44. package/src/core/reporter/index.ts +2 -2
  45. package/src/core/reporter/json.ts +5 -2
  46. package/src/core/runner/assertions.ts +4 -1
  47. package/src/core/runner/executor.ts +132 -37
  48. package/src/core/runner/http-client.ts +40 -5
  49. package/src/core/runner/rate-limiter.ts +131 -0
  50. package/src/core/setup-api.ts +4 -1
  51. package/src/core/workspace/root.ts +94 -0
  52. package/src/db/schema.ts +4 -1
@@ -0,0 +1,94 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { homedir } from "node:os";
4
+
5
+ /**
6
+ * Files / directories that mark a workspace root. Order matters — earlier
7
+ * markers win when more than one is present in the same directory.
8
+ *
9
+ * zond.config.yml — explicit project config (T12)
10
+ * .zond/ — `zond init --here` subdir convention (T19)
11
+ * zond.db — flat layout from `zond init`
12
+ * apis/ — flat layout (collections directory)
13
+ */
14
+ export const WORKSPACE_MARKERS = ["zond.config.yml", ".zond", "zond.db", "apis"] as const;
15
+ export type WorkspaceMarker = (typeof WORKSPACE_MARKERS)[number];
16
+
17
+ export interface WorkspaceInfo {
18
+ /** Absolute path to the workspace root. */
19
+ root: string;
20
+ /** Marker that triggered detection, or "" when fallback (cwd) was used. */
21
+ marker: WorkspaceMarker | "";
22
+ /** True when no marker was found and we fell back to `cwd`. */
23
+ fromFallback: boolean;
24
+ }
25
+
26
+ let warned = false;
27
+
28
+ function hasMarker(dir: string): WorkspaceMarker | null {
29
+ for (const m of WORKSPACE_MARKERS) {
30
+ const p = join(dir, m);
31
+ if (!existsSync(p)) continue;
32
+ // .zond and apis must be directories; zond.config.yml and zond.db must be files
33
+ try {
34
+ const st = statSync(p);
35
+ if (m === ".zond" || m === "apis") {
36
+ if (st.isDirectory()) return m;
37
+ } else if (st.isFile()) {
38
+ return m;
39
+ }
40
+ } catch {
41
+ /* race / permissions — treat as no marker */
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * Walk-up from `cwd` (default `process.cwd()`) to the nearest workspace
49
+ * marker. The walk stops at `os.homedir()` to avoid accidentally picking up
50
+ * `~/apis` or `~/zond.db` when the user runs zond from somewhere unrelated.
51
+ *
52
+ * When no marker is found, returns `{ root: cwd, fromFallback: true }` and
53
+ * prints a one-time stderr warning so the user knows zond is operating in
54
+ * cwd-mode.
55
+ */
56
+ export function findWorkspaceRoot(cwd?: string): WorkspaceInfo {
57
+ const start = resolve(cwd ?? process.cwd());
58
+ const stop = resolve(homedir());
59
+
60
+ let dir = start;
61
+ // Walk strictly while above (or equal to) HOME's length, but include HOME
62
+ // itself as a candidate only when start is inside HOME. If start is outside
63
+ // HOME (e.g. /tmp), walk all the way to "/".
64
+ const insideHome = start === stop || start.startsWith(stop + "/") || start.startsWith(stop + "\\");
65
+
66
+ while (true) {
67
+ const marker = hasMarker(dir);
68
+ if (marker) return { root: dir, marker, fromFallback: false };
69
+
70
+ const parent = dirname(dir);
71
+ if (parent === dir) break; // filesystem root
72
+ if (insideHome && dir === stop) break; // do not climb past HOME
73
+ dir = parent;
74
+ }
75
+
76
+ if (!warned) {
77
+ warned = true;
78
+ process.stderr.write(
79
+ `[zond] no workspace marker found from ${start}; using cwd. ` +
80
+ `Run 'zond init' or create zond.config.yml to anchor the workspace.\n`,
81
+ );
82
+ }
83
+ return { root: start, marker: "", fromFallback: true };
84
+ }
85
+
86
+ /** Resolve `relative` against the workspace root (auto-detected from `cwd`). */
87
+ export function resolveWorkspacePath(relative: string, cwd?: string): string {
88
+ return resolve(findWorkspaceRoot(cwd).root, relative);
89
+ }
90
+
91
+ /** Test helper: reset the one-shot warning latch. */
92
+ export function _resetWorkspaceWarning(): void {
93
+ warned = false;
94
+ }
package/src/db/schema.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import { resolve } from "path";
3
3
  import { existsSync } from "fs";
4
+ import { findWorkspaceRoot } from "../core/workspace/root.ts";
4
5
 
5
6
  let _db: Database | null = null;
6
7
  let _dbPath: string | null = null;
7
8
 
8
9
  export function getDb(dbPath?: string): Database {
9
- const path = dbPath ? resolve(dbPath) : (_dbPath ?? resolve(process.cwd(), "zond.db"));
10
+ const path = dbPath
11
+ ? resolve(dbPath)
12
+ : (_dbPath ?? resolve(findWorkspaceRoot().root, "zond.db"));
10
13
 
11
14
  // If cached connection exists, verify the file still exists
12
15
  if (_db && _dbPath === path && existsSync(path)) return _db;