@frehilm/ordna-core 0.1.3 → 0.2.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/README.md +34 -0
  2. package/dist/config.d.ts +26 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +41 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/git.d.ts +10 -0
  7. package/dist/git.d.ts.map +1 -1
  8. package/dist/git.js +14 -27
  9. package/dist/git.js.map +1 -1
  10. package/dist/index.d.ts +3 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/providers/load.d.ts.map +1 -1
  15. package/dist/providers/load.js +11 -0
  16. package/dist/providers/load.js.map +1 -1
  17. package/dist/schema.d.ts +18 -1
  18. package/dist/schema.d.ts.map +1 -1
  19. package/dist/schema.js.map +1 -1
  20. package/dist/storage/auto-detect.d.ts +82 -0
  21. package/dist/storage/auto-detect.d.ts.map +1 -0
  22. package/dist/storage/auto-detect.js +158 -0
  23. package/dist/storage/auto-detect.js.map +1 -0
  24. package/dist/storage/auto-push.d.ts +36 -0
  25. package/dist/storage/auto-push.d.ts.map +1 -0
  26. package/dist/storage/auto-push.js +100 -0
  27. package/dist/storage/auto-push.js.map +1 -0
  28. package/dist/storage/backend.d.ts +86 -0
  29. package/dist/storage/backend.d.ts.map +1 -0
  30. package/dist/storage/backend.js +14 -0
  31. package/dist/storage/backend.js.map +1 -0
  32. package/dist/storage/backends/file.d.ts +31 -0
  33. package/dist/storage/backends/file.d.ts.map +1 -0
  34. package/dist/storage/backends/file.js +213 -0
  35. package/dist/storage/backends/file.js.map +1 -0
  36. package/dist/storage/backends/hybrid.d.ts +39 -0
  37. package/dist/storage/backends/hybrid.d.ts.map +1 -0
  38. package/dist/storage/backends/hybrid.js +270 -0
  39. package/dist/storage/backends/hybrid.js.map +1 -0
  40. package/dist/storage/backends/namespace.d.ts +55 -0
  41. package/dist/storage/backends/namespace.d.ts.map +1 -0
  42. package/dist/storage/backends/namespace.js +907 -0
  43. package/dist/storage/backends/namespace.js.map +1 -0
  44. package/dist/storage/file-io.d.ts +38 -0
  45. package/dist/storage/file-io.d.ts.map +1 -0
  46. package/dist/storage/file-io.js +69 -0
  47. package/dist/storage/file-io.js.map +1 -0
  48. package/dist/storage/git-ref.d.ts +77 -0
  49. package/dist/storage/git-ref.d.ts.map +1 -0
  50. package/dist/storage/git-ref.js +184 -0
  51. package/dist/storage/git-ref.js.map +1 -0
  52. package/dist/storage/markdown.d.ts +17 -0
  53. package/dist/storage/markdown.d.ts.map +1 -0
  54. package/dist/storage/markdown.js +17 -0
  55. package/dist/storage/markdown.js.map +1 -0
  56. package/dist/storage/sync-ref.d.ts +82 -0
  57. package/dist/storage/sync-ref.d.ts.map +1 -0
  58. package/dist/storage/sync-ref.js +191 -0
  59. package/dist/storage/sync-ref.js.map +1 -0
  60. package/dist/store.d.ts +56 -8
  61. package/dist/store.d.ts.map +1 -1
  62. package/dist/store.js +93 -115
  63. package/dist/store.js.map +1 -1
  64. package/dist/watcher.d.ts +33 -1
  65. package/dist/watcher.d.ts.map +1 -1
  66. package/dist/watcher.js +12 -30
  67. package/dist/watcher.js.map +1 -1
  68. package/package.json +1 -1
package/README.md CHANGED
@@ -117,6 +117,40 @@ webPort: 7420 # consumed by @frehilm/ordna-web
117
117
 
118
118
  The last entry of `statuses` is the **terminal status** for the dependency gate.
119
119
 
120
+ ## Storage modes
121
+
122
+ Ordna ships three storage backends. Pick one with a single config key:
123
+
124
+ ```yaml
125
+ storage: file # default
126
+ # storage: hybrid # files + synced ID allocator + audit log in git
127
+ # storage: namespace # tasks as git refs; working tree stays clean
128
+ ```
129
+
130
+ | Mode | Where tasks live | Working tree | Requires git | Use case |
131
+ |---|---|---|---|---|
132
+ | `file` | `tasks/*.md` | yes | no | Single-machine, agent-friendly, the default. |
133
+ | `hybrid` | `tasks/*.md` + `refs/ordna/state` (next-id + audit log) | yes | yes | Multi-machine collaboration; prevents two offline writers picking the same ID. |
134
+ | `namespace` | `refs/ordna/tasks/<id>` (blobs only) | untouched | yes | Decentralised, working-tree-clean, sync via standard `git push`/`fetch`. |
135
+
136
+ `schema: backlog` is only supported with `storage: file`. `hybrid` and `namespace` require a git repository.
137
+
138
+ ### Auto-detection
139
+
140
+ When no `.ordna/config.yaml` exists, Ordna inspects the directory and picks a mode:
141
+
142
+ 1. `refs/ordna/tasks/*` refs exist → `namespace`
143
+ 2. `refs/ordna/state` ref exists → `hybrid`
144
+ 3. `tasks/*.md` files exist → `file`
145
+ 4. cwd is a git repo (none of the above) → prompts the user (TUI modal, web setup page, CLI 1/2/3 on TTY)
146
+ 5. else (no git, no signals) → silently runs in `file` mode
147
+
148
+ Confident detections (1–3) auto-write `.ordna/config.yaml` so the choice is durable across runs and visible to anyone reading the repo.
149
+
150
+ ### `ORDNA_STORAGE` env var
151
+
152
+ Set `ORDNA_STORAGE=file|hybrid|namespace` to override both the config file and auto-detection for a single process invocation. Useful for CI (predictable storage mode, no on-disk side effects) and for tests pinning a specific mode against arbitrary directories.
153
+
120
154
  ## Backlog.md compatibility
121
155
 
122
156
  Ordna reads [Backlog.md](https://github.com/MrLesk/Backlog.md) repos out of the box. The parser normalizes both field sets:
package/dist/config.d.ts CHANGED
@@ -7,6 +7,20 @@ export declare const configSchema: z.ZodObject<{
7
7
  idPrefix: z.ZodDefault<z.ZodString>;
8
8
  zeroPaddedIds: z.ZodDefault<z.ZodNumber>;
9
9
  webPort: z.ZodDefault<z.ZodNumber>;
10
+ storage: z.ZodDefault<z.ZodEnum<["file", "hybrid", "namespace"]>>;
11
+ namespace: z.ZodDefault<z.ZodObject<{
12
+ pollIntervalMs: z.ZodDefault<z.ZodNumber>;
13
+ autoFetchIntervalMs: z.ZodDefault<z.ZodNumber>;
14
+ autoRenumberOnConflict: z.ZodDefault<z.ZodBoolean>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ pollIntervalMs: number;
17
+ autoFetchIntervalMs: number;
18
+ autoRenumberOnConflict: boolean;
19
+ }, {
20
+ pollIntervalMs?: number | undefined;
21
+ autoFetchIntervalMs?: number | undefined;
22
+ autoRenumberOnConflict?: boolean | undefined;
23
+ }>>;
10
24
  }, "strip", z.ZodTypeAny, {
11
25
  tasksDir: string;
12
26
  schema: "ordna" | "backlog";
@@ -14,6 +28,12 @@ export declare const configSchema: z.ZodObject<{
14
28
  idPrefix: string;
15
29
  zeroPaddedIds: number;
16
30
  webPort: number;
31
+ namespace: {
32
+ pollIntervalMs: number;
33
+ autoFetchIntervalMs: number;
34
+ autoRenumberOnConflict: boolean;
35
+ };
36
+ storage: "file" | "hybrid" | "namespace";
17
37
  }, {
18
38
  tasksDir?: string | undefined;
19
39
  schema?: "ordna" | "backlog" | undefined;
@@ -21,6 +41,12 @@ export declare const configSchema: z.ZodObject<{
21
41
  idPrefix?: string | undefined;
22
42
  zeroPaddedIds?: number | undefined;
23
43
  webPort?: number | undefined;
44
+ namespace?: {
45
+ pollIntervalMs?: number | undefined;
46
+ autoFetchIntervalMs?: number | undefined;
47
+ autoRenumberOnConflict?: boolean | undefined;
48
+ } | undefined;
49
+ storage?: "file" | "hybrid" | "namespace" | undefined;
24
50
  }>;
25
51
  export type OrdnaConfig = z.infer<typeof configSchema>;
26
52
  export declare const DEFAULT_CONFIG: OrdnaConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;EAOvB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,cAAc,EAAE,WAAoC,CAAC;AAIlE,MAAM,WAAW,iBAAiB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,WAAW,CAYvE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAgB,GAAG,MAAM,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAEjE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCvB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,cAAc,EAAE,WAAoC,CAAC;AAIlE,MAAM,WAAW,iBAAiB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,WAAW,CA6BvE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAgB,GAAG,MAAM,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAEjE"}
package/dist/config.js CHANGED
@@ -9,6 +9,33 @@ export const configSchema = z.object({
9
9
  idPrefix: z.string().default("T"),
10
10
  zeroPaddedIds: z.number().int().min(0).max(10).default(3),
11
11
  webPort: z.number().int().min(1).max(65535).default(7420),
12
+ // T-031: storage mode selector. "file" (current default) keeps the
13
+ // existing on-disk layout. "hybrid" adds a sync ref for the next-id
14
+ // allocator + audit log. "namespace" (T-032) stores tasks as git
15
+ // blobs under `refs/ordna/tasks/<id>` with no working-tree presence.
16
+ storage: z.enum(["file", "hybrid", "namespace"]).default("file"),
17
+ // T-032: namespace-mode tuning. Polling interval for the watcher
18
+ // (refs have no kernel-level change-notification path, so polling
19
+ // is the only reliable mechanism). Default 1s. `autoFetchIntervalMs`
20
+ // runs `git fetch origin '+refs/ordna/tasks/*:refs/ordna/tasks/*'`
21
+ // in the background so other machines' updates land without manual
22
+ // pulls; set to 0 to disable auto-fetch entirely (manual fetch via
23
+ // the TUI / web button still works). `autoRenumberOnConflict`
24
+ // controls whether a push-rejection on a colliding create silently
25
+ // reallocates a fresh ID for the local task (true, default) or
26
+ // surfaces a loud error (false, for projects where stable IDs in
27
+ // commit messages / external links are load-bearing).
28
+ namespace: z
29
+ .object({
30
+ pollIntervalMs: z.number().int().min(50).default(1000),
31
+ autoFetchIntervalMs: z.number().int().min(0).default(60000),
32
+ autoRenumberOnConflict: z.boolean().default(true),
33
+ })
34
+ .default({
35
+ pollIntervalMs: 1000,
36
+ autoFetchIntervalMs: 60000,
37
+ autoRenumberOnConflict: true,
38
+ }),
12
39
  });
13
40
  export const DEFAULT_CONFIG = configSchema.parse({});
14
41
  const CONFIG_PATH = ".ordna/config.yaml";
@@ -20,7 +47,20 @@ export function loadConfig(options = {}) {
20
47
  const raw = readFileSync(configFile, "utf8");
21
48
  fromFile = parseYaml(raw) ?? {};
22
49
  }
23
- const merged = { ...fromFile, ...(options.overrides ?? {}) };
50
+ const merged = {
51
+ ...fromFile,
52
+ ...(options.overrides ?? {}),
53
+ };
54
+ // T-033: `ORDNA_STORAGE` is a runtime override — when set to one of
55
+ // the known modes, it wins over whatever the YAML says. CI uses
56
+ // this to pin storage without writing a file; tests use it to
57
+ // exercise specific modes without polluting the test directory.
58
+ const envStorage = process.env.ORDNA_STORAGE;
59
+ if (envStorage === "file" ||
60
+ envStorage === "hybrid" ||
61
+ envStorage === "namespace") {
62
+ merged.storage = envStorage;
63
+ }
24
64
  return configSchema.parse(merged);
25
65
  }
26
66
  export function resolveTasksDir(config, cwd = process.cwd()) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACrD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACzD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAElE,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAOzC,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACzD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAE1C,IAAI,QAAQ,GAAY,EAAE,CAAC;IAC3B,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7C,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,GAAI,QAAmB,EAAE,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC;IACzE,OAAO,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACvE,OAAO,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACpD,OAAO,MAAM,CAAC,MAAM,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts CHANGED
@@ -1,3 +1,13 @@
1
1
  import type { StoreContext } from "./store.js";
2
+ /**
3
+ * Commit pending task changes.
4
+ *
5
+ * Delegates to the active backend's optional `commit()` method. The
6
+ * built-in file backend implements it (stages the tasks directory and
7
+ * runs `git commit`); future non-file backends (hybrid keeps it for
8
+ * the file half; namespace deliberately omits it because tasks aren't
9
+ * in the working tree) leave it undefined, in which case this throws
10
+ * a clear error pointing the user at the right sync flow.
11
+ */
2
12
  export declare function commitTasks(ctx: StoreContext, message?: string): Promise<void>;
3
13
  //# sourceMappingURL=git.d.ts.map
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAqB/C,wBAAsB,WAAW,CAChC,GAAG,EAAE,YAAY,EACjB,OAAO,SAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAOf"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf"}
package/dist/git.js CHANGED
@@ -1,30 +1,17 @@
1
- import { spawn } from "node:child_process";
2
- function run(cwd, args) {
3
- return new Promise((resolve, reject) => {
4
- const proc = spawn("git", args, { cwd });
5
- let stdout = "";
6
- let stderr = "";
7
- proc.stdout.on("data", (chunk) => {
8
- stdout += chunk.toString();
9
- });
10
- proc.stderr.on("data", (chunk) => {
11
- stderr += chunk.toString();
12
- });
13
- proc.on("error", reject);
14
- proc.on("close", (code) => {
15
- if (code === 0)
16
- resolve({ stdout, stderr });
17
- else
18
- reject(new Error(`git ${args.join(" ")} failed (${code}): ${stderr.trim()}`));
19
- });
20
- });
21
- }
22
- export async function commitTasks(ctx, message = "chore(tasks): update") {
23
- await run(ctx.cwd, ["add", "--", ctx.config.tasksDir]);
24
- const status = await run(ctx.cwd, ["status", "--porcelain", "--", ctx.config.tasksDir]);
25
- if (status.stdout.trim().length === 0) {
26
- throw new Error("No task changes to commit.");
1
+ /**
2
+ * Commit pending task changes.
3
+ *
4
+ * Delegates to the active backend's optional `commit()` method. The
5
+ * built-in file backend implements it (stages the tasks directory and
6
+ * runs `git commit`); future non-file backends (hybrid keeps it for
7
+ * the file half; namespace deliberately omits it because tasks aren't
8
+ * in the working tree) leave it undefined, in which case this throws
9
+ * a clear error pointing the user at the right sync flow.
10
+ */
11
+ export async function commitTasks(ctx, message) {
12
+ if (!ctx.backend.commit) {
13
+ throw new Error(`Backend "${ctx.backend.kind}" does not support \`ordna commit\`. Use the backend's own sync flow instead.`);
27
14
  }
28
- await run(ctx.cwd, ["commit", "-m", message, "--", ctx.config.tasksDir]);
15
+ return ctx.backend.commit(message);
29
16
  }
30
17
  //# sourceMappingURL=git.js.map
package/dist/git.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;;gBACvC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,GAAiB,EACjB,OAAO,GAAG,sBAAsB;IAEhC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxF,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,GAAiB,EACjB,OAAgB;IAEhB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACd,YAAY,GAAG,CAAC,OAAO,CAAC,IAAI,+EAA+E,CAC3G,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,7 +4,9 @@ export { extractIdFromFilename, formatId, nextId, parseId } from "./ids.js";
4
4
  export { extractAcceptanceCriteria, findSection, parseTask, parseTaskFile, splitSections, } from "./parser.js";
5
5
  export type { AcceptanceItem, Priority, RawFrontmatter, SchemaMode, Section, Task, TaskCreateInput, TaskUpdateInput, } from "./schema.js";
6
6
  export { BACKLOG_BODY_HEADINGS, BODY_HEADING_ALIASES, FRONTMATTER_ALIASES, ORDNA_BODY_HEADINGS, frontmatterSchema, priorityEnum, } from "./schema.js";
7
- export { ARCHIVED_STATUS, createContext, createTask, deleteTask, getTask, isKnownStatus, listTasks, moveTask, updateTask, type ListTasksOptions, type StoreContext, } from "./store.js";
7
+ export { ARCHIVED_STATUS, canFetch, createContext, createTask, deleteTask, fetchTasks, getTask, isKnownStatus, listTasks, moveTask, updateTask, type ListTasksOptions, type StoreContext, } from "./store.js";
8
+ export type { FetchResult } from "./storage/backend.js";
8
9
  export { defaultSectionsFor, serializeTask } from "./writer.js";
9
10
  export { watchTasks, type TaskEvent, type TaskEventListener, type WatchOptions } from "./watcher.js";
11
+ export { type DetectedMode, NeedsModeSelection, detectStorageMode, ensureStorageConfig, readEnvStorageMode, writeStorageConfig, } from "./storage/auto-detect.js";
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,WAAW,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EACN,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,cAAc,EACd,QAAQ,EACR,cAAc,EACd,UAAU,EACV,OAAO,EACP,IAAI,EACJ,eAAe,EACf,eAAe,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,WAAW,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EACN,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,cAAc,EACd,QAAQ,EACR,cAAc,EACd,UAAU,EACV,OAAO,EACP,IAAI,EACJ,eAAe,EACf,eAAe,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,eAAe,EACf,QAAQ,EACR,aAAa,EACb,UAAU,EACV,UAAU,EACV,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EACN,KAAK,YAAY,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@ export { commitTasks } from "./git.js";
3
3
  export { extractIdFromFilename, formatId, nextId, parseId } from "./ids.js";
4
4
  export { extractAcceptanceCriteria, findSection, parseTask, parseTaskFile, splitSections, } from "./parser.js";
5
5
  export { BACKLOG_BODY_HEADINGS, BODY_HEADING_ALIASES, FRONTMATTER_ALIASES, ORDNA_BODY_HEADINGS, frontmatterSchema, priorityEnum, } from "./schema.js";
6
- export { ARCHIVED_STATUS, createContext, createTask, deleteTask, getTask, isKnownStatus, listTasks, moveTask, updateTask, } from "./store.js";
6
+ export { ARCHIVED_STATUS, canFetch, createContext, createTask, deleteTask, fetchTasks, getTask, isKnownStatus, listTasks, moveTask, updateTask, } from "./store.js";
7
7
  export { defaultSectionsFor, serializeTask } from "./writer.js";
8
8
  export { watchTasks } from "./watcher.js";
9
+ export { NeedsModeSelection, detectStorageMode, ensureStorageConfig, readEnvStorageMode, writeStorageConfig, } from "./storage/auto-detect.js";
9
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,eAAe,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EACN,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,GACb,MAAM,aAAa,CAAC;AAWrB,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,UAAU,GAGV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,UAAU,EAA6D,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,eAAe,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EACN,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,GACb,MAAM,aAAa,CAAC;AAWrB,OAAO,EACN,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,eAAe,EACf,QAAQ,EACR,aAAa,EACb,UAAU,EACV,UAAU,EACV,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,UAAU,GAGV,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,UAAU,EAA6D,MAAM,cAAc,CAAC;AACrG,OAAO,EAEN,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/providers/load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAC5B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,MAAM,KACP,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAa1C;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CACjC,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,YAAY,CAAC,CA6BvB"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/providers/load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAC5B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,MAAM,KACP,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AA0B1C;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CACjC,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,YAAY,CAAC,CA6BvB"}
@@ -4,9 +4,20 @@ function isModuleNotFoundError(err, packageName) {
4
4
  if (!(err instanceof Error))
5
5
  return false;
6
6
  const code = err.code;
7
+ // Native Node ESM / CJS resolver.
7
8
  if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
8
9
  return err.message.includes(packageName);
9
10
  }
11
+ // Vite-node (used by Vitest) wraps unresolved imports without setting a
12
+ // recognizable error code. Match its message shape so the loader still
13
+ // surfaces the install hint when exercised from the test runner.
14
+ const msg = err.message;
15
+ if (msg.includes(packageName) &&
16
+ (msg.startsWith("Failed to load url") ||
17
+ msg.startsWith("Cannot find package") ||
18
+ msg.startsWith("Cannot find module"))) {
19
+ return true;
20
+ }
10
21
  return false;
11
22
  }
12
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/providers/load.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAY7C,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAEhD,SAAS,qBAAqB,CAAC,GAAY,EAAE,WAAmB;IAC/D,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;IACjD,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACpE,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,MAAmB,EACnB,GAAW;IAEX,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE7B,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,IAAI,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,qBAAqB,GAAG,IAAI,EAAE,CAAC;IACtD,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACd,aAAa,IAAI,kCAAkC,WAAW,EAAE,CAChE,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAI,GAAoC,CAAC,cAAc,CAAC;IACrE,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACd,qBAAqB,WAAW,2KAA2K,CAC3M,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAO,OAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/providers/load.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAY7C,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAEhD,SAAS,qBAAqB,CAAC,GAAY,EAAE,WAAmB;IAC/D,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;IACjD,kCAAkC;IAClC,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACpE,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IACD,wEAAwE;IACxE,uEAAuE;IACvE,iEAAiE;IACjE,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;IACxB,IACC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;QACzB,CAAC,GAAG,CAAC,UAAU,CAAC,oBAAoB,CAAC;YACpC,GAAG,CAAC,UAAU,CAAC,qBAAqB,CAAC;YACrC,GAAG,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,EACrC,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,MAAmB,EACnB,GAAW;IAEX,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE7B,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACrB,OAAO,IAAI,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,qBAAqB,GAAG,IAAI,EAAE,CAAC;IACtD,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACd,aAAa,IAAI,kCAAkC,WAAW,EAAE,CAChE,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAI,GAAoC,CAAC,cAAc,CAAC;IACrE,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACd,qBAAqB,WAAW,2KAA2K,CAC3M,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAO,OAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AACjB,CAAC"}
package/dist/schema.d.ts CHANGED
@@ -22,8 +22,25 @@ export interface Task {
22
22
  updated_at: string;
23
23
  sections: Section[];
24
24
  extra_frontmatter: Record<string, unknown>;
25
- filePath: string;
25
+ /**
26
+ * On-disk location of the task file.
27
+ *
28
+ * Set by the file and hybrid backends (tasks live as `.md` files).
29
+ * **Unset** by the namespace backend — tasks there live as git
30
+ * blobs at `refs/ordna/tasks/<id>` with no working-tree presence.
31
+ * Consumers must guard against `undefined` (the CLI editor launcher
32
+ * and the create-command path-log already do).
33
+ */
34
+ filePath?: string;
26
35
  rawContent: string;
36
+ /**
37
+ * Most recent previous id this task had, if the namespace backend
38
+ * auto-renumbered it on a push collision. Surfaced as a
39
+ * "previously known as X" banner in the UIs. Populated only by the
40
+ * namespace backend (it reads the state ref's audit log on each
41
+ * `get`/`list`); file and hybrid leave it `undefined`.
42
+ */
43
+ renamed_from?: string;
27
44
  }
28
45
  export interface TaskCreateInput {
29
46
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAUxD,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,eAAO,MAAM,qBAAqB;;;;;;CAMxB,CAAC;AAEX,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAMzD,CAAC;AAEF,eAAO,MAAM,YAAY,sCAAoC,CAAC;AAE9D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAgBf,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAUxD,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,eAAO,MAAM,qBAAqB;;;;;;CAMxB,CAAC;AAEX,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAMzD,CAAC;AAEF,eAAO,MAAM,YAAY,sCAAoC,CAAC;AAE9D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAgBf,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Result of `detectStorageMode`. Three confident outcomes
3
+ * (`file` / `hybrid` / `namespace`) lead to auto-configuration; `ask`
4
+ * needs a user prompt; `default-file` is the "no signals, no git"
5
+ * fallback that runs in file mode without writing a config (the user
6
+ * might `git init` later).
7
+ */
8
+ export type DetectedMode = {
9
+ mode: "file" | "hybrid" | "namespace";
10
+ reason: string;
11
+ } | {
12
+ mode: "ask";
13
+ reason: string;
14
+ } | {
15
+ mode: "default-file";
16
+ reason: string;
17
+ };
18
+ /**
19
+ * Thrown when `ensureStorageConfig` detects a git repo with no storage
20
+ * signals and no config — there's no defensible default, so the
21
+ * consumer must prompt the user. The TUI catches this and shows a
22
+ * modal, the web server catches it and serves a setup page, the CLI
23
+ * one-shots prompt on TTY or fail with a clear hint.
24
+ */
25
+ export declare class NeedsModeSelection extends Error {
26
+ readonly cwd: string;
27
+ readonly reason: string;
28
+ constructor(cwd: string, reason: string);
29
+ }
30
+ /**
31
+ * Inspect `cwd` for storage signals. Pure detection — never writes,
32
+ * never creates anything. Returns a `DetectedMode` for the caller to
33
+ * act on.
34
+ *
35
+ * Detection order:
36
+ * 1. `refs/ordna/tasks/*` exist → `namespace`
37
+ * 2. `refs/ordna/state` exists → `hybrid`
38
+ * 3. `tasks/*.md` files exist → `file`
39
+ * 4. cwd is a git repo (none of the above) → `ask`
40
+ * 5. else → `default-file`
41
+ *
42
+ * Uses `git for-each-ref` to authoritative-check refs (handles packed
43
+ * refs after `git gc` correctly, where direct filesystem reads of
44
+ * `.git/refs/...` would miss them).
45
+ */
46
+ export declare function detectStorageMode(cwd: string): Promise<DetectedMode>;
47
+ /**
48
+ * Compose detection + write into one call.
49
+ *
50
+ * - If `ORDNA_STORAGE` is set to a valid mode, return immediately
51
+ * without writing or detecting. The caller relies on `loadConfig`
52
+ * honouring the env var.
53
+ * - If `.ordna/config.yaml` already exists, return immediately.
54
+ * - Otherwise run `detectStorageMode` and:
55
+ * - `file` / `hybrid` / `namespace` → write the config with the
56
+ * detected storage key
57
+ * - `ask` → throw `NeedsModeSelection`
58
+ * - `default-file` → return without writing (let the caller fall
59
+ * back to in-memory file mode; if the user later `git init`s,
60
+ * detection re-evaluates from scratch on next run)
61
+ */
62
+ export declare function ensureStorageConfig(cwd: string): Promise<void>;
63
+ /**
64
+ * Write a minimal `.ordna/config.yaml` containing the chosen storage
65
+ * mode. Other config keys are left to the schema defaults so the file
66
+ * doesn't pin values the user hasn't deliberately chosen.
67
+ *
68
+ * Idempotent — overwrites an existing config file. Callers that don't
69
+ * want that should check first (see `ensureStorageConfig`).
70
+ */
71
+ export declare function writeStorageConfig(cwd: string, storage: "file" | "hybrid" | "namespace"): void;
72
+ /**
73
+ * Read `ORDNA_STORAGE` from the environment, validating against the
74
+ * three known modes. Anything else (including unset / empty) returns
75
+ * `null` so the normal detection path runs.
76
+ *
77
+ * Exported so `config.ts` can apply the same override when reading the
78
+ * YAML — keeps the env-var semantics consistent across the two
79
+ * entrypoints.
80
+ */
81
+ export declare function readEnvStorageMode(): "file" | "hybrid" | "namespace" | null;
82
+ //# sourceMappingURL=auto-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-detect.d.ts","sourceRoot":"","sources":["../../src/storage/auto-detect.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACrB;IAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAE3B,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,MAAM;gBADd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM;CAO/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA8C1E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GACtC,IAAI,CAKN;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAC/B,MAAM,GACN,QAAQ,GACR,WAAW,GACX,IAAI,CAIN"}
@@ -0,0 +1,158 @@
1
+ import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { GitRunner } from "./git-ref.js";
4
+ /**
5
+ * Thrown when `ensureStorageConfig` detects a git repo with no storage
6
+ * signals and no config — there's no defensible default, so the
7
+ * consumer must prompt the user. The TUI catches this and shows a
8
+ * modal, the web server catches it and serves a setup page, the CLI
9
+ * one-shots prompt on TTY or fail with a clear hint.
10
+ */
11
+ export class NeedsModeSelection extends Error {
12
+ cwd;
13
+ reason;
14
+ constructor(cwd, reason) {
15
+ super(`Ordna needs to know which storage mode to use in ${cwd}. ${reason}`);
16
+ this.cwd = cwd;
17
+ this.reason = reason;
18
+ this.name = "NeedsModeSelection";
19
+ }
20
+ }
21
+ /**
22
+ * Inspect `cwd` for storage signals. Pure detection — never writes,
23
+ * never creates anything. Returns a `DetectedMode` for the caller to
24
+ * act on.
25
+ *
26
+ * Detection order:
27
+ * 1. `refs/ordna/tasks/*` exist → `namespace`
28
+ * 2. `refs/ordna/state` exists → `hybrid`
29
+ * 3. `tasks/*.md` files exist → `file`
30
+ * 4. cwd is a git repo (none of the above) → `ask`
31
+ * 5. else → `default-file`
32
+ *
33
+ * Uses `git for-each-ref` to authoritative-check refs (handles packed
34
+ * refs after `git gc` correctly, where direct filesystem reads of
35
+ * `.git/refs/...` would miss them).
36
+ */
37
+ export async function detectStorageMode(cwd) {
38
+ const isGitRepo = isGitWorkingTree(cwd);
39
+ if (isGitRepo) {
40
+ const git = new GitRunner(cwd);
41
+ const taskRefs = await git.forEachRef("refs/ordna/tasks/*");
42
+ if (taskRefs.length > 0) {
43
+ return {
44
+ mode: "namespace",
45
+ reason: `found ${taskRefs.length} ref(s) under refs/ordna/tasks/`,
46
+ };
47
+ }
48
+ const stateRefs = await git.forEachRef("refs/ordna/state");
49
+ if (stateRefs.length > 0) {
50
+ return { mode: "hybrid", reason: "found refs/ordna/state" };
51
+ }
52
+ }
53
+ // File-mode signal: `tasks/` with at least one `.md` file. Without
54
+ // a loaded config we can only check the default path; non-default
55
+ // `tasksDir` configurations imply a config exists, in which case
56
+ // detection never runs.
57
+ const tasksDir = join(cwd, "tasks");
58
+ if (existsSync(tasksDir)) {
59
+ try {
60
+ const entries = readdirSync(tasksDir, { withFileTypes: true });
61
+ const hasMd = entries.some((e) => e.isFile() && e.name.endsWith(".md"));
62
+ if (hasMd) {
63
+ return { mode: "file", reason: "found tasks/*.md files" };
64
+ }
65
+ }
66
+ catch {
67
+ // readdirSync error (permissions, etc.) — treat as "no signal."
68
+ }
69
+ }
70
+ if (isGitRepo) {
71
+ return {
72
+ mode: "ask",
73
+ reason: "no storage signals found, but this is a git repo",
74
+ };
75
+ }
76
+ return {
77
+ mode: "default-file",
78
+ reason: "no git, no existing tasks — defaulting to file mode",
79
+ };
80
+ }
81
+ /**
82
+ * Compose detection + write into one call.
83
+ *
84
+ * - If `ORDNA_STORAGE` is set to a valid mode, return immediately
85
+ * without writing or detecting. The caller relies on `loadConfig`
86
+ * honouring the env var.
87
+ * - If `.ordna/config.yaml` already exists, return immediately.
88
+ * - Otherwise run `detectStorageMode` and:
89
+ * - `file` / `hybrid` / `namespace` → write the config with the
90
+ * detected storage key
91
+ * - `ask` → throw `NeedsModeSelection`
92
+ * - `default-file` → return without writing (let the caller fall
93
+ * back to in-memory file mode; if the user later `git init`s,
94
+ * detection re-evaluates from scratch on next run)
95
+ */
96
+ export async function ensureStorageConfig(cwd) {
97
+ const envMode = readEnvStorageMode();
98
+ if (envMode) {
99
+ // Env var is a runtime override; do not write the config file.
100
+ return;
101
+ }
102
+ if (configFileExists(cwd)) {
103
+ return;
104
+ }
105
+ const detected = await detectStorageMode(cwd);
106
+ switch (detected.mode) {
107
+ case "file":
108
+ case "hybrid":
109
+ case "namespace":
110
+ writeStorageConfig(cwd, detected.mode);
111
+ return;
112
+ case "ask":
113
+ throw new NeedsModeSelection(cwd, detected.reason);
114
+ case "default-file":
115
+ return; // run with in-memory defaults; don't litter
116
+ }
117
+ }
118
+ /**
119
+ * Write a minimal `.ordna/config.yaml` containing the chosen storage
120
+ * mode. Other config keys are left to the schema defaults so the file
121
+ * doesn't pin values the user hasn't deliberately chosen.
122
+ *
123
+ * Idempotent — overwrites an existing config file. Callers that don't
124
+ * want that should check first (see `ensureStorageConfig`).
125
+ */
126
+ export function writeStorageConfig(cwd, storage) {
127
+ const configDir = join(cwd, ".ordna");
128
+ if (!existsSync(configDir))
129
+ mkdirSync(configDir, { recursive: true });
130
+ const body = `# Ordna config — auto-written from storage detection.\nstorage: ${storage}\n`;
131
+ writeFileSync(join(configDir, "config.yaml"), body, "utf8");
132
+ }
133
+ /**
134
+ * Read `ORDNA_STORAGE` from the environment, validating against the
135
+ * three known modes. Anything else (including unset / empty) returns
136
+ * `null` so the normal detection path runs.
137
+ *
138
+ * Exported so `config.ts` can apply the same override when reading the
139
+ * YAML — keeps the env-var semantics consistent across the two
140
+ * entrypoints.
141
+ */
142
+ export function readEnvStorageMode() {
143
+ const raw = process.env.ORDNA_STORAGE;
144
+ if (raw === "file" || raw === "hybrid" || raw === "namespace")
145
+ return raw;
146
+ return null;
147
+ }
148
+ function configFileExists(cwd) {
149
+ return existsSync(join(cwd, ".ordna", "config.yaml"));
150
+ }
151
+ function isGitWorkingTree(cwd) {
152
+ // `.git` can be a directory (regular repo), a file (worktree
153
+ // pointing at the main repo's gitdir), or absent. `existsSync` on
154
+ // `<cwd>/.git` covers all three cases — present (any type) means
155
+ // "this is a git checkout."
156
+ return existsSync(join(cwd, ".git"));
157
+ }
158
+ //# sourceMappingURL=auto-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-detect.js","sourceRoot":"","sources":["../../src/storage/auto-detect.ts"],"names":[],"mappings":"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"}