@frehilm/ordna-core 0.1.4 → 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 (65) 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/schema.d.ts +18 -1
  15. package/dist/schema.d.ts.map +1 -1
  16. package/dist/schema.js.map +1 -1
  17. package/dist/storage/auto-detect.d.ts +82 -0
  18. package/dist/storage/auto-detect.d.ts.map +1 -0
  19. package/dist/storage/auto-detect.js +158 -0
  20. package/dist/storage/auto-detect.js.map +1 -0
  21. package/dist/storage/auto-push.d.ts +36 -0
  22. package/dist/storage/auto-push.d.ts.map +1 -0
  23. package/dist/storage/auto-push.js +100 -0
  24. package/dist/storage/auto-push.js.map +1 -0
  25. package/dist/storage/backend.d.ts +86 -0
  26. package/dist/storage/backend.d.ts.map +1 -0
  27. package/dist/storage/backend.js +14 -0
  28. package/dist/storage/backend.js.map +1 -0
  29. package/dist/storage/backends/file.d.ts +31 -0
  30. package/dist/storage/backends/file.d.ts.map +1 -0
  31. package/dist/storage/backends/file.js +213 -0
  32. package/dist/storage/backends/file.js.map +1 -0
  33. package/dist/storage/backends/hybrid.d.ts +39 -0
  34. package/dist/storage/backends/hybrid.d.ts.map +1 -0
  35. package/dist/storage/backends/hybrid.js +270 -0
  36. package/dist/storage/backends/hybrid.js.map +1 -0
  37. package/dist/storage/backends/namespace.d.ts +55 -0
  38. package/dist/storage/backends/namespace.d.ts.map +1 -0
  39. package/dist/storage/backends/namespace.js +907 -0
  40. package/dist/storage/backends/namespace.js.map +1 -0
  41. package/dist/storage/file-io.d.ts +38 -0
  42. package/dist/storage/file-io.d.ts.map +1 -0
  43. package/dist/storage/file-io.js +69 -0
  44. package/dist/storage/file-io.js.map +1 -0
  45. package/dist/storage/git-ref.d.ts +77 -0
  46. package/dist/storage/git-ref.d.ts.map +1 -0
  47. package/dist/storage/git-ref.js +184 -0
  48. package/dist/storage/git-ref.js.map +1 -0
  49. package/dist/storage/markdown.d.ts +17 -0
  50. package/dist/storage/markdown.d.ts.map +1 -0
  51. package/dist/storage/markdown.js +17 -0
  52. package/dist/storage/markdown.js.map +1 -0
  53. package/dist/storage/sync-ref.d.ts +82 -0
  54. package/dist/storage/sync-ref.d.ts.map +1 -0
  55. package/dist/storage/sync-ref.js +191 -0
  56. package/dist/storage/sync-ref.js.map +1 -0
  57. package/dist/store.d.ts +56 -8
  58. package/dist/store.d.ts.map +1 -1
  59. package/dist/store.js +93 -115
  60. package/dist/store.js.map +1 -1
  61. package/dist/watcher.d.ts +33 -1
  62. package/dist/watcher.d.ts.map +1 -1
  63. package/dist/watcher.js +12 -30
  64. package/dist/watcher.js.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,191 @@
1
+ import { formatId } from "../ids.js";
2
+ const DEFAULT_REF = "refs/ordna/state";
3
+ const EMPTY_OID = ""; // CAS sentinel for "must not exist"
4
+ const EMPTY_STATE = { next_id: 1, ops: [] };
5
+ /**
6
+ * Wraps a single git ref carrying a JSON `SyncState` blob.
7
+ *
8
+ * The CAS pattern: every write reads the current blob, computes the
9
+ * new state, hashes the new blob, and `update-ref`s with the old OID
10
+ * as the expected-old value. If the ref has moved underneath us
11
+ * (another writer slipped in), the CAS fails non-fast-forward and we
12
+ * fetch + retry once. Beyond that, we surface a clear "diverged"
13
+ * error so the user can intervene.
14
+ *
15
+ * Reads are cached in memory until invalidated (after a CAS conflict)
16
+ * or after a successful write (cache is updated to the new state).
17
+ */
18
+ export class SyncRef {
19
+ git;
20
+ refname;
21
+ #cached = null;
22
+ constructor(git, refname = DEFAULT_REF) {
23
+ this.git = git;
24
+ this.refname = refname;
25
+ }
26
+ /**
27
+ * Read the current state. Returns an empty state if the ref
28
+ * doesn't yet exist. Hits the cache when available.
29
+ */
30
+ async read() {
31
+ if (this.#cached)
32
+ return this.#cached.state;
33
+ const fresh = await this.#readUncached();
34
+ this.#cached = fresh;
35
+ return fresh.state;
36
+ }
37
+ /** Drop the cache. Next `read()` hits the ref again. */
38
+ invalidate() {
39
+ this.#cached = null;
40
+ }
41
+ /**
42
+ * Seed the ref with `initial` only if it doesn't yet exist. Used by
43
+ * namespace mode to migrate pre-state-ref repos: scan existing
44
+ * `refs/ordna/tasks/*` for the max id, then call this with
45
+ * `{ next_id: max + 1, ops: [] }`. Safe to call concurrently — if
46
+ * another process initialises first, we just adopt its value.
47
+ */
48
+ async ensureInitialized(initial) {
49
+ const fresh = await this.#readUncached();
50
+ if (fresh.oid !== null) {
51
+ // Already initialised by someone (us in a previous run, or
52
+ // another process racing with us). Adopt their state.
53
+ this.#cached = fresh;
54
+ return;
55
+ }
56
+ try {
57
+ await this.#writeCAS(null, initial);
58
+ }
59
+ catch (err) {
60
+ if (isCASConflict(err)) {
61
+ // Lost the bootstrap race; another writer landed first.
62
+ // Re-read to pick up their state.
63
+ this.invalidate();
64
+ await this.read();
65
+ return;
66
+ }
67
+ throw err;
68
+ }
69
+ }
70
+ async #readUncached() {
71
+ const refs = await this.git.forEachRef(this.refname);
72
+ const match = refs.find((r) => r.refname === this.refname);
73
+ if (!match)
74
+ return { oid: null, state: structuredClone(EMPTY_STATE) };
75
+ try {
76
+ const raw = await this.git.catBlob(match.oid);
77
+ const parsed = JSON.parse(raw);
78
+ // Defensive normalisation: tolerate missing fields in old blobs.
79
+ return {
80
+ oid: match.oid,
81
+ state: {
82
+ next_id: typeof parsed.next_id === "number" ? parsed.next_id : 1,
83
+ ops: Array.isArray(parsed.ops) ? parsed.ops : [],
84
+ },
85
+ };
86
+ }
87
+ catch {
88
+ // Corrupt blob — fall back to empty state and let the next
89
+ // write overwrite it. Surfacing an error here would block
90
+ // every read; we prefer self-healing.
91
+ return { oid: match.oid, state: structuredClone(EMPTY_STATE) };
92
+ }
93
+ }
94
+ /**
95
+ * Allocate the next id, bump the counter, and persist atomically.
96
+ * Returns the formatted id (e.g. `T-007`) for the caller.
97
+ *
98
+ * On CAS conflict, fetches the ref from origin (if any) and
99
+ * retries once. Further conflicts throw a clear error.
100
+ */
101
+ async allocateNextId(config) {
102
+ return this.#withRetry(async () => {
103
+ const { oid, state } = await this.#readUncachedAndCache();
104
+ const allocated = formatId(config, state.next_id);
105
+ const nextState = {
106
+ next_id: state.next_id + 1,
107
+ ops: state.ops,
108
+ };
109
+ await this.#writeCAS(oid, nextState);
110
+ return allocated;
111
+ });
112
+ }
113
+ /** Append a single op to the audit log and persist atomically. */
114
+ async appendOp(op) {
115
+ await this.#withRetry(async () => {
116
+ const { oid, state } = await this.#readUncachedAndCache();
117
+ const nextState = {
118
+ next_id: state.next_id,
119
+ ops: [...state.ops, op],
120
+ };
121
+ await this.#writeCAS(oid, nextState);
122
+ });
123
+ }
124
+ async #readUncachedAndCache() {
125
+ const fresh = await this.#readUncached();
126
+ this.#cached = fresh;
127
+ return fresh;
128
+ }
129
+ async #writeCAS(expectedOid, nextState) {
130
+ const blob = `${JSON.stringify(nextState, null, 2)}\n`;
131
+ const newOid = await this.git.hashObject(blob);
132
+ // CAS: `""` if the ref must not exist; otherwise the captured oid.
133
+ const expectedOld = expectedOid ?? EMPTY_OID;
134
+ await this.git.updateRef(this.refname, newOid, expectedOld);
135
+ // Successful write: update the cache to the new state.
136
+ this.#cached = { oid: newOid, state: nextState };
137
+ }
138
+ /**
139
+ * Run an operation that does read-then-CAS-write. On CAS conflict,
140
+ * fetch the ref (best-effort if a remote exists) and retry once.
141
+ */
142
+ async #withRetry(operation) {
143
+ try {
144
+ return await operation();
145
+ }
146
+ catch (err) {
147
+ if (!isCASConflict(err))
148
+ throw err;
149
+ // Fetch from origin if it exists, then retry. If fetch fails
150
+ // (no remote, network down), the retry still re-reads local
151
+ // state via forEachRef so concurrent in-process writers are
152
+ // handled too.
153
+ if (await this.git.hasRemote()) {
154
+ try {
155
+ await this.git.fetchRef(this.refname);
156
+ }
157
+ catch {
158
+ // Best-effort; fall through to retry against local state.
159
+ }
160
+ }
161
+ this.invalidate();
162
+ try {
163
+ return await operation();
164
+ }
165
+ catch (retryErr) {
166
+ if (isCASConflict(retryErr)) {
167
+ throw new Error(`ordna: sync ref ${this.refname} diverged. Run \`git fetch origin '+${this.refname}:${this.refname}'\` to reconcile, then retry.`);
168
+ }
169
+ throw retryErr;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ /**
175
+ * Heuristic: a CAS conflict surfaces as a `git update-ref` failure
176
+ * whose stderr mentions either a missing-ref / wrong-old / non-fast-
177
+ * forward condition. We pattern-match on the thrown message rather
178
+ * than introducing a typed error from `GitRunner` — keeps the runner
179
+ * generic.
180
+ */
181
+ function isCASConflict(err) {
182
+ if (!(err instanceof Error))
183
+ return false;
184
+ const msg = err.message.toLowerCase();
185
+ return (msg.includes("update-ref") &&
186
+ (msg.includes("cannot lock ref") ||
187
+ msg.includes("is at") ||
188
+ msg.includes("expected") ||
189
+ msg.includes("missing")));
190
+ }
191
+ //# sourceMappingURL=sync-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-ref.js","sourceRoot":"","sources":["../../src/storage/sync-ref.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -1,22 +1,70 @@
1
1
  import { type OrdnaConfig } from "./config.js";
2
2
  import type { Task, TaskCreateInput, TaskUpdateInput } from "./schema.js";
3
+ import { type Backend, type FetchResult, type ListOptions, ARCHIVED_STATUS, isKnownStatus } from "./storage/backend.js";
4
+ /**
5
+ * Public context object passed to every store function. The `backend`
6
+ * field carries the storage strategy chosen at `createContext` time;
7
+ * the strategy interface itself is private (not exported from
8
+ * `index.ts`).
9
+ *
10
+ * `backend` is typed as `Backend`, which is unexported, so consumers
11
+ * can read the field but can't declare their own `Backend`-typed
12
+ * variables without importing internals. That's intentional — the
13
+ * field is public for now (future cleanup may hide it behind a
14
+ * method) but the interface stays a TS-internal seam.
15
+ */
3
16
  export interface StoreContext {
4
17
  cwd: string;
5
18
  config: OrdnaConfig;
6
19
  tasksDir: string;
20
+ backend: Backend;
7
21
  }
8
- export declare const ARCHIVED_STATUS = "archived";
9
- export declare function isKnownStatus(config: OrdnaConfig, status: string): boolean;
10
- export interface ListTasksOptions {
11
- status?: string;
12
- assignee?: string;
13
- tag?: string;
14
- }
22
+ export { ARCHIVED_STATUS, isKnownStatus };
23
+ /**
24
+ * @deprecated Use `ListOptions` from the backend layer (not exported).
25
+ * Kept as the public type name for back-compat with
26
+ * 0.1.x consumers. Same shape.
27
+ */
28
+ export type ListTasksOptions = ListOptions;
29
+ /**
30
+ * Build a context bound to the active working directory.
31
+ *
32
+ * Stays SYNCHRONOUS. The chosen backend is constructed cheaply (no
33
+ * I/O); the first method call on the backend triggers lazy `init()`
34
+ * internally. This is what lets the IDE that embeds core construct
35
+ * contexts without awaiting.
36
+ *
37
+ * Backend selection is driven by `config.storage`. Combinations that
38
+ * make no sense are rejected eagerly so the user sees a clear error
39
+ * up front rather than a confusing failure deep inside a method call.
40
+ *
41
+ * - `storage: hybrid` requires a git repository (`.git/` present at
42
+ * `cwd` or any parent)
43
+ * - `storage: hybrid` + `schema: backlog` is rejected — the audit-
44
+ * log model and Backlog's filename conventions are out of scope
45
+ * for v1 to combine
46
+ * - `storage: namespace` is reserved for T-032; rejected for now
47
+ */
15
48
  export declare function createContext(cwd?: string): StoreContext;
16
- export declare function listTasks(ctx?: StoreContext, options?: ListTasksOptions): Promise<Task[]>;
49
+ export declare function listTasks(ctx?: StoreContext, options?: ListOptions): Promise<Task[]>;
17
50
  export declare function getTask(id: string, ctx?: StoreContext): Promise<Task | null>;
18
51
  export declare function createTask(input: TaskCreateInput, ctx?: StoreContext): Promise<Task>;
19
52
  export declare function updateTask(id: string, patch: TaskUpdateInput, ctx?: StoreContext): Promise<Task>;
53
+ /**
54
+ * Move a task to a new status. The `depends_on` gate stays in core so
55
+ * backends don't have to re-implement Ordna's business rules — the
56
+ * gate fires here, then the actual write is delegated to the backend.
57
+ */
20
58
  export declare function moveTask(id: string, status: string, ctx?: StoreContext): Promise<Task>;
21
59
  export declare function deleteTask(id: string, ctx?: StoreContext): Promise<void>;
60
+ /**
61
+ * Pull remote updates into the active backend. Only namespace
62
+ * implements this in v1 — see `Backend.fetch` for the rationale.
63
+ *
64
+ * File / hybrid throw a clear error so callers (UI buttons, CLI
65
+ * commands) can show a useful message rather than silently no-op.
66
+ */
67
+ export declare function fetchTasks(ctx?: StoreContext): Promise<FetchResult>;
68
+ /** True if the active backend exposes a `fetch()` capability. */
69
+ export declare function canFetch(ctx: StoreContext): boolean;
22
70
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,aAAa,CAAC;AAG5E,OAAO,KAAK,EAAuB,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG/F,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG1E;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,aAAa,CAAC,GAAG,SAAgB,GAAG,YAAY,CAI/D;AAwBD,wBAAsB,SAAS,CAC9B,GAAG,GAAE,YAA8B,EACnC,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,IAAI,EAAE,CAAC,CAuBjB;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,YAA8B,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAGnG;AAED,wBAAsB,UAAU,CAC/B,KAAK,EAAE,eAAe,EACtB,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,wBAAsB,UAAU,CAC/B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,QAAQ,CAC7B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,YAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/F"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EACN,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,eAAe,EACf,aAAa,EACb,MAAM,sBAAsB,CAAC;AAK9B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAE1C;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CA4BvE;AAkBD,wBAAsB,SAAS,CAC9B,GAAG,GAAE,YAA8B,EACnC,OAAO,GAAE,WAAgB,GACvB,OAAO,CAAC,IAAI,EAAE,CAAC,CAEjB;AAED,wBAAsB,OAAO,CAC5B,EAAE,EAAE,MAAM,EACV,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAEtB;AAED,wBAAsB,UAAU,CAC/B,KAAK,EAAE,eAAe,EACtB,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,UAAU,CAC/B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC7B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,UAAU,CAC/B,EAAE,EAAE,MAAM,EACV,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC/B,GAAG,GAAE,YAA8B,GACjC,OAAO,CAAC,WAAW,CAAC,CAOtB;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAEnD"}
package/dist/store.js CHANGED
@@ -1,135 +1,99 @@
1
- import { existsSync, mkdirSync, readdirSync } from "node:fs";
2
- import { readFile, unlink, writeFile } from "node:fs/promises";
3
- import { basename, join } from "node:path";
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
4
3
  import { loadConfig, resolveTasksDir } from "./config.js";
5
- import { formatId, nextId, parseId } from "./ids.js";
6
- import { parseTask } from "./parser.js";
7
- import { defaultSectionsFor, serializeTask } from "./writer.js";
8
- export const ARCHIVED_STATUS = "archived";
9
- export function isKnownStatus(config, status) {
10
- if (status === ARCHIVED_STATUS)
11
- return true;
12
- return config.statuses.includes(status);
13
- }
4
+ import { ARCHIVED_STATUS, isKnownStatus, } from "./storage/backend.js";
5
+ import { FileBackend } from "./storage/backends/file.js";
6
+ import { HybridBackend } from "./storage/backends/hybrid.js";
7
+ import { NamespaceBackend } from "./storage/backends/namespace.js";
8
+ export { ARCHIVED_STATUS, isKnownStatus };
9
+ /**
10
+ * Build a context bound to the active working directory.
11
+ *
12
+ * Stays SYNCHRONOUS. The chosen backend is constructed cheaply (no
13
+ * I/O); the first method call on the backend triggers lazy `init()`
14
+ * internally. This is what lets the IDE that embeds core construct
15
+ * contexts without awaiting.
16
+ *
17
+ * Backend selection is driven by `config.storage`. Combinations that
18
+ * make no sense are rejected eagerly so the user sees a clear error
19
+ * up front rather than a confusing failure deep inside a method call.
20
+ *
21
+ * - `storage: hybrid` requires a git repository (`.git/` present at
22
+ * `cwd` or any parent)
23
+ * - `storage: hybrid` + `schema: backlog` is rejected — the audit-
24
+ * log model and Backlog's filename conventions are out of scope
25
+ * for v1 to combine
26
+ * - `storage: namespace` is reserved for T-032; rejected for now
27
+ */
14
28
  export function createContext(cwd = process.cwd()) {
15
29
  const config = loadConfig({ cwd });
16
30
  const tasksDir = resolveTasksDir(config, cwd);
17
- return { cwd, config, tasksDir };
18
- }
19
- function today() {
20
- return new Date().toISOString().slice(0, 10);
21
- }
22
- function slugifyTitle(title) {
23
- return title
24
- .toLowerCase()
25
- .replace(/[^a-z0-9]+/g, "-")
26
- .replace(/^-+|-+$/g, "")
27
- .slice(0, 60);
31
+ if (config.storage === "hybrid") {
32
+ assertGitRepo(cwd, "hybrid");
33
+ if (config.schema === "backlog") {
34
+ throw new Error("ordna: `storage: hybrid` is not supported with `schema: backlog` in v1. Use `schema: ordna`, or stay on `storage: file` if you need Backlog.md compatibility.");
35
+ }
36
+ const backend = new HybridBackend(cwd, config, tasksDir);
37
+ return { cwd, config, tasksDir, backend };
38
+ }
39
+ if (config.storage === "namespace") {
40
+ assertGitRepo(cwd, "namespace");
41
+ if (config.schema === "backlog") {
42
+ throw new Error("ordna: `storage: namespace` is not supported with `schema: backlog`. Backlog's filename convention has no analogue in a ref-only store; use `schema: ordna`, or stay on `storage: file` if you need Backlog.md compatibility.");
43
+ }
44
+ const backend = new NamespaceBackend(cwd, config);
45
+ return { cwd, config, tasksDir, backend };
46
+ }
47
+ const backend = new FileBackend(cwd, config, tasksDir);
48
+ return { cwd, config, tasksDir, backend };
28
49
  }
29
- function filenameFor(id, title, mode, config) {
30
- if (mode === "backlog") {
31
- const numeric = parseId(config, id);
32
- const numericPart = numeric ?? id;
33
- const slug = slugifyTitle(title) || "task";
34
- return `task-${numericPart} - ${slug}.md`;
50
+ function assertGitRepo(cwd, mode) {
51
+ // Walk up from cwd looking for a `.git/` directory. A bare repo
52
+ // would lack the working tree but still has `.git` as a file
53
+ // pointer or directory; we accept either.
54
+ let dir = cwd;
55
+ for (let i = 0; i < 64; i++) {
56
+ if (existsSync(join(dir, ".git")))
57
+ return;
58
+ const parent = join(dir, "..");
59
+ if (parent === dir)
60
+ break;
61
+ dir = parent;
35
62
  }
36
- return `${id}.md`;
63
+ throw new Error(`ordna: \`storage: ${mode}\` requires a git repository. Run \`git init\` in this directory, or switch back to \`storage: file\` in .ordna/config.yaml.`);
37
64
  }
38
65
  export async function listTasks(ctx = createContext(), options = {}) {
39
- if (!existsSync(ctx.tasksDir))
40
- return [];
41
- const entries = readdirSync(ctx.tasksDir, { withFileTypes: true });
42
- const tasks = [];
43
- for (const entry of entries) {
44
- if (!entry.isFile() || !entry.name.endsWith(".md"))
45
- continue;
46
- const filePath = join(ctx.tasksDir, entry.name);
47
- const raw = await readFile(filePath, "utf8");
48
- try {
49
- tasks.push(parseTask(raw, filePath));
50
- }
51
- catch {
52
- // Skip malformed tasks silently; surfaced via dedicated validator later.
53
- }
54
- }
55
- let filtered = tasks;
56
- if (options.status)
57
- filtered = filtered.filter((t) => t.status === options.status);
58
- if (options.assignee)
59
- filtered = filtered.filter((t) => t.assignee === options.assignee);
60
- if (options.tag)
61
- filtered = filtered.filter((t) => t.tags.includes(options.tag));
62
- filtered.sort((a, b) => a.id.localeCompare(b.id, undefined, { numeric: true }));
63
- return filtered;
66
+ return ctx.backend.list(options);
64
67
  }
65
68
  export async function getTask(id, ctx = createContext()) {
66
- const tasks = await listTasks(ctx);
67
- return tasks.find((t) => t.id === id) ?? null;
69
+ return ctx.backend.get(id);
68
70
  }
69
71
  export async function createTask(input, ctx = createContext()) {
70
- if (!existsSync(ctx.tasksDir))
71
- mkdirSync(ctx.tasksDir, { recursive: true });
72
- const id = nextId(ctx.config, ctx.tasksDir);
73
- const status = input.status ?? ctx.config.statuses[0];
74
- if (!status)
75
- throw new Error("Config has no statuses defined.");
76
- if (!isKnownStatus(ctx.config, status)) {
77
- throw new Error(`Status "${status}" is not in configured statuses.`);
78
- }
79
- const now = today();
80
- const task = {
81
- id,
82
- title: input.title,
83
- status,
84
- assignee: input.assignee ?? null,
85
- priority: input.priority ?? null,
86
- tags: input.tags ?? [],
87
- depends_on: input.depends_on ?? [],
88
- created_at: now,
89
- updated_at: now,
90
- sections: defaultSectionsFor(ctx.config.schema),
91
- extra_frontmatter: {},
92
- filePath: "",
93
- rawContent: "",
94
- };
95
- const filename = filenameFor(id, task.title, ctx.config.schema, ctx.config);
96
- task.filePath = join(ctx.tasksDir, filename);
97
- const serialized = serializeTask(task, ctx.config.schema);
98
- task.rawContent = serialized;
99
- await writeFile(task.filePath, serialized, "utf8");
100
- return task;
72
+ return ctx.backend.create(input);
101
73
  }
102
74
  export async function updateTask(id, patch, ctx = createContext()) {
103
- const existing = await getTask(id, ctx);
104
- if (!existing)
105
- throw new Error(`Task ${id} not found.`);
106
- const next = {
107
- ...existing,
108
- title: patch.title ?? existing.title,
109
- status: patch.status ?? existing.status,
110
- assignee: patch.assignee !== undefined ? patch.assignee : existing.assignee,
111
- priority: patch.priority !== undefined ? patch.priority : existing.priority,
112
- tags: patch.tags ?? existing.tags,
113
- depends_on: patch.depends_on ?? existing.depends_on,
114
- sections: patch.sections ?? existing.sections,
115
- updated_at: today(),
116
- };
117
- if (next.status !== existing.status && !isKnownStatus(ctx.config, next.status)) {
118
- throw new Error(`Status "${next.status}" is not in configured statuses.`);
75
+ if (patch.status !== undefined &&
76
+ !isKnownStatus(ctx.config, patch.status)) {
77
+ throw new Error(`Status "${patch.status}" is not in configured statuses.`);
119
78
  }
120
- const serialized = serializeTask(next, ctx.config.schema);
121
- next.rawContent = serialized;
122
- await writeFile(existing.filePath, serialized, "utf8");
123
- return next;
79
+ return ctx.backend.update(id, patch);
124
80
  }
81
+ /**
82
+ * Move a task to a new status. The `depends_on` gate stays in core so
83
+ * backends don't have to re-implement Ordna's business rules — the
84
+ * gate fires here, then the actual write is delegated to the backend.
85
+ */
125
86
  export async function moveTask(id, status, ctx = createContext()) {
87
+ if (!isKnownStatus(ctx.config, status)) {
88
+ throw new Error(`Status "${status}" is not in configured statuses.`);
89
+ }
126
90
  const terminal = ctx.config.statuses[ctx.config.statuses.length - 1];
127
91
  if (status === terminal) {
128
- const task = await getTask(id, ctx);
92
+ const task = await ctx.backend.get(id);
129
93
  if (!task)
130
94
  throw new Error(`Task ${id} not found.`);
131
95
  if (task.depends_on.length > 0) {
132
- const all = await listTasks(ctx);
96
+ const all = await ctx.backend.list();
133
97
  const byId = new Map(all.map((t) => [t.id, t]));
134
98
  const unfinished = task.depends_on.filter((dep) => {
135
99
  const d = byId.get(dep);
@@ -140,12 +104,26 @@ export async function moveTask(id, status, ctx = createContext()) {
140
104
  }
141
105
  }
142
106
  }
143
- return updateTask(id, { status }, ctx);
107
+ return ctx.backend.update(id, { status });
144
108
  }
145
109
  export async function deleteTask(id, ctx = createContext()) {
146
- const task = await getTask(id, ctx);
147
- if (!task)
148
- throw new Error(`Task ${id} not found.`);
149
- await unlink(task.filePath);
110
+ return ctx.backend.delete(id);
111
+ }
112
+ /**
113
+ * Pull remote updates into the active backend. Only namespace
114
+ * implements this in v1 — see `Backend.fetch` for the rationale.
115
+ *
116
+ * File / hybrid throw a clear error so callers (UI buttons, CLI
117
+ * commands) can show a useful message rather than silently no-op.
118
+ */
119
+ export async function fetchTasks(ctx = createContext()) {
120
+ if (typeof ctx.backend.fetch !== "function") {
121
+ throw new Error(`storage: ${ctx.backend.kind} doesn't support fetch (namespace only in v1)`);
122
+ }
123
+ return ctx.backend.fetch();
124
+ }
125
+ /** True if the active backend exposes a `fetch()` capability. */
126
+ export function canFetch(ctx) {
127
+ return typeof ctx.backend.fetch === "function";
150
128
  }
151
129
  //# sourceMappingURL=store.js.map
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/watcher.d.ts CHANGED
@@ -1,5 +1,18 @@
1
1
  import type { StoreContext } from "./store.js";
2
2
  import type { Task } from "./schema.js";
3
+ /**
4
+ * Event emitted by the backend's watcher.
5
+ *
6
+ * - `added` : a new task appeared
7
+ * - `changed` : an existing task's content changed
8
+ * - `removed` : a task was deleted; carries `filePath` for file/hybrid
9
+ * (and the synthetic `ref:<refname>` for namespace)
10
+ * - `renamed` : namespace auto-renumber resolved a push-collision by
11
+ * reallocating a fresh ID; carries both the old and new
12
+ * IDs so the UI can show "previously known as X" and
13
+ * clear any cached views keyed on `oldId`. Only the
14
+ * namespace backend emits this.
15
+ */
3
16
  export type TaskEvent = {
4
17
  type: "added";
5
18
  task: Task;
@@ -9,10 +22,29 @@ export type TaskEvent = {
9
22
  } | {
10
23
  type: "removed";
11
24
  filePath: string;
25
+ } | {
26
+ type: "renamed";
27
+ oldId: string;
28
+ newId: string;
29
+ task: Task;
12
30
  };
13
31
  export type TaskEventListener = (event: TaskEvent) => void;
14
32
  export interface WatchOptions {
33
+ /**
34
+ * Reserved for future use. Today this is unused — the active
35
+ * backend controls its own watch behaviour.
36
+ */
15
37
  ignoreInitial?: boolean;
16
38
  }
17
- export declare function watchTasks(ctx: StoreContext, listener: TaskEventListener, options?: WatchOptions): () => Promise<void>;
39
+ /**
40
+ * Subscribe to task changes.
41
+ *
42
+ * Delegates to the active backend's `watch` method. The file backend
43
+ * uses chokidar on `<tasksDir>`; future remote backends (hybrid uses
44
+ * the same chokidar pattern; namespace polls `git for-each-ref`)
45
+ * plug their own implementations behind the same listener contract.
46
+ *
47
+ * Returns an unsubscribe function. Call it on shutdown.
48
+ */
49
+ export declare function watchTasks(ctx: StoreContext, listener: TaskEventListener, _options?: WatchOptions): () => Promise<void>;
18
50
  //# sourceMappingURL=watcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,SAAS,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,UAAU,CACzB,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,YAAiB,GACxB,MAAM,OAAO,CAAC,IAAI,CAAC,CA8BrB"}
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACzB,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,GAAE,YAAiB,GACzB,MAAM,OAAO,CAAC,IAAI,CAAC,CAErB"}