@adhd/backlog 0.1.9 → 1.0.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 (60) hide show
  1. package/CHANGELOG.md +80 -47
  2. package/README.md +332 -81
  3. package/api.d.ts +146 -0
  4. package/cli.d.ts +45 -18
  5. package/env.d.ts +23 -3
  6. package/envelope.d.ts +163 -0
  7. package/index.d.ts +11 -10
  8. package/index.js +531 -173
  9. package/index.mjs +30039 -15879
  10. package/install-skill.d.ts +23 -0
  11. package/package.json +50 -15
  12. package/query/card.d.ts +31 -0
  13. package/query/get.d.ts +11 -0
  14. package/query/index.d.ts +67 -0
  15. package/query/markdown.d.ts +11 -0
  16. package/query/query.d.ts +131 -0
  17. package/query/resolve.d.ts +123 -0
  18. package/query/types.d.ts +450 -0
  19. package/query/views/registry.d.ts +43 -0
  20. package/query/views/semantic.d.ts +101 -0
  21. package/query/views/stats.d.ts +109 -0
  22. package/search-shortcut.d.ts +79 -0
  23. package/serve.d.ts +18 -0
  24. package/server.d.ts +139 -4
  25. package/skill/SKILL.md +619 -138
  26. package/store/graph-backlog-store.d.ts +80 -17
  27. package/store/immediate-retry.d.ts +24 -13
  28. package/store/type-policy.d.ts +4 -0
  29. package/store/vocabulary-guard.d.ts +52 -0
  30. package/write/audit.d.ts +36 -0
  31. package/write/bootstrap.d.ts +123 -0
  32. package/write/catalog.d.ts +351 -0
  33. package/write/claim-lease.d.ts +21 -0
  34. package/write/claim.d.ts +80 -0
  35. package/write/create-issue.d.ts +250 -0
  36. package/write/delete.d.ts +39 -0
  37. package/write/embed-drain.d.ts +68 -0
  38. package/write/embedding-observer.d.ts +80 -0
  39. package/write/errors.d.ts +303 -0
  40. package/write/issue-status.d.ts +10 -0
  41. package/write/move.d.ts +70 -0
  42. package/write/relate.d.ts +52 -0
  43. package/write/transition.d.ts +60 -0
  44. package/write/tx.d.ts +344 -0
  45. package/write/update.d.ts +81 -0
  46. package/client.d.ts +0 -174
  47. package/markdown.d.ts +0 -75
  48. package/migration-admin.d.ts +0 -26
  49. package/model.d.ts +0 -437
  50. package/store/audit-log.d.ts +0 -16
  51. package/store/claim.d.ts +0 -24
  52. package/store/crud.d.ts +0 -62
  53. package/store/ids.d.ts +0 -24
  54. package/store/lifecycle.d.ts +0 -36
  55. package/store/mapping.d.ts +0 -101
  56. package/store/mutate-metadata.d.ts +0 -8
  57. package/store/query.d.ts +0 -68
  58. package/store/repo-migration.d.ts +0 -51
  59. package/store/serve-lock.d.ts +0 -42
  60. package/store/structure.d.ts +0 -66
package/cli.d.ts CHANGED
@@ -94,11 +94,11 @@ export declare const USE_PLUGINS: readonly Plugin[];
94
94
  export declare function resolveMountNamespaces(usePlugins: readonly Plugin[], operations: readonly Operation[], host: string): Set<string>;
95
95
  /**
96
96
  * Prepends `prefix` (the real, namespace-qualified command path segments
97
- * every `client.ts` export shares — see {@link resolveCommandPrefix}) to a
98
- * user-typed argv, so `backlog get-item --repo … --human-id …` (what a
99
- * consumer actually types — the bin's own name is never part of `argv`)
100
- * resolves against the cli-output plugin's command table, which is keyed by
101
- * the FULL internal path (`['backlog', 'get-item']`).
97
+ * every `api.ts` export shares — see {@link resolveCommandPrefix}) to a
98
+ * user-typed argv, so `backlog get --input '{"uid":"…"}'` (what a consumer
99
+ * actually types — the bin's own name is never part of `argv`) resolves
100
+ * against the cli-output plugin's command table, which is keyed by the FULL
101
+ * internal path (`['backlog', 'get']`).
102
102
  *
103
103
  * Idempotent / defensive:
104
104
  * - Empty argv is returned unchanged — `run()` treats `argv.length === 0`
@@ -130,20 +130,47 @@ export interface RunBacklogCliOpts {
130
130
  adhdRoot?: string;
131
131
  cwd?: string;
132
132
  signal?: AbortSignal;
133
+ /** Explicit-parameter-first namespace override — see
134
+ * `BuildBacklogEnvOptions.namespace`'s doc comment and `--namespace`
135
+ * (SPEC.md §5c). A parsed `--namespace <value>` (or a programmatic
136
+ * caller's `optsIn.namespace`) sets this directly; a programmatic caller
137
+ * may also pass it without going through argv at all. */
138
+ namespace?: string;
133
139
  }
134
140
  /**
135
- * Opens (or reuses) the backlog store + env, then dispatches EXACTLY ONE CLI
136
- * command live through `@adhd/apigen-plugin-cli-output`'s `run()` — no code
137
- * generation, no bespoke argument parsing. Mirrors `startBacklogServer`'s
138
- * env→store→ctx→`buildBacklogApigenPackage` setup precisely; the only
139
- * divergence is transport-specific: `cliPlugin.run()` is one-shot (it
140
- * resolves after dispatching a single command rather than listening), so
141
- * there is no `Promise.all` of long-lived transports to await here.
141
+ * backlog CLI had no isolation mode at all originally, so trying a
142
+ * destructive or unfamiliar command meant either risking the real graph or
143
+ * hand-rolling env-var isolation (`ADHD_BACKLOG_SCOPE`/`ADHD_ROOT`) from
144
+ * scratch. `--namespace <value>` (SPEC.md §5c), recognized ANYWHERE in argv
145
+ * (like `--help`), strips itself out and validates against
146
+ * `backlogEnvironmentSpec.namespaces` (`'production'` | `'test'` |
147
+ * `'sandbox'`). Omitted ⇒ `'production'` (D2) — no behavior change for the
148
+ * overwhelmingly common case.
142
149
  *
143
- * @param argv Command + flags, WITHOUT the `backlog` bin name (e.g.
144
- * `['get-item', '--repo', 'org/repo', '--human-id', 'BUG-1']`). Defaults
145
- * to `process.argv.slice(2)` — the real CLI invocation's own argv — when
146
- * omitted, matching `cliPlugin.run()`'s own `resolveArgv()` fallback
147
- * convention.
150
+ * `--namespace sandbox` additionally layers ephemeral-root-minting on top of
151
+ * namespace selection (D5): it points the SAME `adhdRoot` test-isolation
152
+ * knob `BuildBacklogEnvOptions` already exposes (previously test-only —
153
+ * `cli.spec.ts`'s `runBin` is the proof this mechanism genuinely isolates)
154
+ * at a freshly created, per-invocation temp directory: `backlog --namespace
155
+ * sandbox create …` writes into a throwaway store, never the real one, and
156
+ * prints exactly where so a caller can inspect or clean it up. It is NOT
157
+ * auto-deleted — a caller may want to re-run further commands against the
158
+ * SAME sandbox by passing `ADHD_ROOT=<printed path>` explicitly on a later
159
+ * invocation; deleting it behind the caller's back the moment this process
160
+ * exits would defeat that.
148
161
  */
149
- export declare function runBacklogCli(argv?: string[], opts?: RunBacklogCliOpts): Promise<void>;
162
+ export declare function stripNamespaceFlag(argv: readonly string[]): {
163
+ argv: string[];
164
+ namespace: string | undefined;
165
+ /** `true` iff `--namespace`/`--namespace=` was present but supplied no
166
+ * value (bare trailing flag, or `--namespace=` with nothing after `=`) —
167
+ * distinct from "flag absent" so the caller can reject it (D3) instead of
168
+ * silently falling through to the default. */
169
+ missingValue: boolean;
170
+ /** `true` iff `--namespace`/`--namespace=` appeared MORE THAN ONCE with
171
+ * two DIFFERING values. Every occurrence is always stripped from the
172
+ * returned `argv` regardless of count. Two occurrences with the SAME
173
+ * value are not a conflict (idempotent). */
174
+ conflicting: boolean;
175
+ };
176
+ export declare function runBacklogCli(argvIn?: string[], optsIn?: RunBacklogCliOpts): Promise<void>;
package/env.d.ts CHANGED
@@ -9,8 +9,16 @@ export interface BacklogConfig {
9
9
  readonly logging: {
10
10
  readonly level: string;
11
11
  };
12
- readonly migration: {
13
- readonly phase: string;
12
+ /**
13
+ * RAG-SPEC.md §1.6 — the opt-in embedding/vector stack. `enabled` defaults
14
+ * to FALSE: an unconfigured build must behave exactly as it did before RAG
15
+ * existed (every semantic input answers `RagNotConfiguredError`, §5a), so
16
+ * a host opts IN deliberately and nothing is ever switched on implicitly.
17
+ */
18
+ readonly embedding: {
19
+ readonly enabled: boolean;
20
+ readonly provider: string;
21
+ readonly model: string;
14
22
  };
15
23
  }
16
24
  export declare const backlogEnvironmentSpec: EnvironmentSpec<BacklogConfig>;
@@ -24,16 +32,28 @@ export declare function resolveBacklogScope(explicit?: Scope): Scope;
24
32
  * `instanceId` exist purely for test isolation (constructing an `Environment`
25
33
  * rooted at a temp directory instead of the real machine's `~/.adhd`), mirror
26
34
  * `EnvironmentOptions`'s own test-isolation fields.
35
+ *
36
+ * `namespace` is EXPLICIT-PARAMETER-FIRST, deliberately with no env-var
37
+ * fallback (unlike `scope`'s `resolveBacklogScope` cascade above) — a
38
+ * namespace selection must be threaded as a real function parameter (CLI
39
+ * flag → this field → `EnvironmentOptions.namespace`), never resolved from
40
+ * ambient `process.env`, so it can never be silently defeated by a shell
41
+ * variable a caller forgot was set the way `ADHD_ROOT` previously defeated
42
+ * `--sandbox` (`BUG-BACKLOG-SANDBOX-SILENT-BYPASS-001`, cli.ts). Omitted ⇒
43
+ * `'production'` (the first-declared namespace — see `backlogEnvironmentSpec`
44
+ * — every existing caller that never passes this keeps resolving there,
45
+ * unchanged).
27
46
  */
28
47
  export interface BuildBacklogEnvOptions {
29
48
  scope?: Scope;
30
49
  adhdRoot?: string;
31
50
  cwd?: string;
32
51
  instanceId?: string;
52
+ namespace?: string;
33
53
  }
34
54
  export declare function buildBacklogEnv(options?: BuildBacklogEnvOptions): Environment<BacklogConfig>;
35
55
  /**
36
- * BUG-002: the effective SQLite backlog-graph DB path. Every store-open site
56
+ * BUG-002: the effective backlog graph DB path. Every store-open site
37
57
  * (`cli.ts`'s `runBacklogCli`, `server.ts`'s `startBacklogServer`) must
38
58
  * resolve the path through THIS helper — never `env.files.db` directly —
39
59
  * or a consumer setting `ADHD_BACKLOG_DATABASE_PATH` silently hits the
package/envelope.d.ts ADDED
@@ -0,0 +1,163 @@
1
+ /**
2
+ * envelope.ts — the transport-facing response envelope: its closed error-code
3
+ * union, the exit codes a CLI host keys off, and the constructors/guards every
4
+ * surface (CLI, MCP, HTTP) branches on.
5
+ *
6
+ * **Why this is its own module.** This machinery previously lived in a
7
+ * 2,936-line god-module alongside the entire superseded application layer. It
8
+ * is the one piece of that module the replacement layer genuinely needs, so
9
+ * keeping it there meant the god-module could never be deleted. Nothing here
10
+ * depends on any item/store type — the envelope is deliberately about SHAPE,
11
+ * not about what is being carried — so it has zero internal imports and sits
12
+ * at the bottom of the dependency graph.
13
+ *
14
+ * **The error-code union is DERIVED, not curated.** The set below is exactly
15
+ * the image of {@link toEnvelopeCode}'s class→code mapping. That rule matters:
16
+ * an earlier attempt to prune the union by grepping for literal code strings
17
+ * found four codes "unused" and would have deleted two that are load-bearing,
18
+ * because codes are never written as literals at the throw site — they are
19
+ * produced by mapping a thrown error class. A code belongs here if and only if
20
+ * some error class maps to it. Add a class, add its code; delete the last
21
+ * class that maps to a code, delete the code.
22
+ */
23
+ /**
24
+ * The closed union of envelope error codes.
25
+ *
26
+ * Each member names the error class(es) that produce it, so the derivation
27
+ * rule in this file's header can be checked by reading rather than inferred.
28
+ */
29
+ export declare const BACKLOG_ERROR_CODES: readonly ["not_found", "item_not_found", "invalid_argument", "validation", "store_busy", "rag_not_configured", "conflict", "precondition_failed", "internal"];
30
+ /** The closed union of envelope error codes. See {@link BACKLOG_ERROR_CODES}. */
31
+ export type BacklogErrorCode = (typeof BACKLOG_ERROR_CODES)[number];
32
+ /**
33
+ * Runtime membership test for the closed union. The union is only genuinely
34
+ * "closed" if something checks it at runtime — a transport that hand-built an
35
+ * envelope with a typo'd code would otherwise ship an error no agent can
36
+ * switch on, and TypeScript cannot see across a JSON boundary.
37
+ */
38
+ export declare function isBacklogErrorCode(value: unknown): value is BacklogErrorCode;
39
+ /**
40
+ * Error code → CLI process exit code.
41
+ *
42
+ * Verified against `@adhd/apigen-base-errors`' `CLI_EXIT_CODE`
43
+ * (`invalid_argument: 2, not_found: 4, internal: 1`); these codes extend that
44
+ * table without remapping any of it.
45
+ *
46
+ * The load-bearing property is that a caller can distinguish outcomes the
47
+ * exit code alone collapses: `item_not_found` and `internal` both exit 1, so
48
+ * they MUST remain distinct `code` values.
49
+ */
50
+ export declare const BACKLOG_EXIT_CODE: Readonly<Record<BacklogErrorCode, number>>;
51
+ /**
52
+ * `error.details`. `retryable`/`retryAfterMs` exist so an agent knows whether
53
+ * to retry a `store_busy` and with what backoff instead of hot-looping.
54
+ * Open-ended beyond those: individual codes attach their own evidence.
55
+ */
56
+ export interface IOutcomeErrorDetails {
57
+ /** True only for transient codes (today: `store_busy`). */
58
+ retryable?: boolean;
59
+ /** Suggested backoff in milliseconds; only meaningful when `retryable`. */
60
+ retryAfterMs?: number;
61
+ /**
62
+ * Internal doc/plan reference for an `invalid_argument` whose underlying
63
+ * reason cites internal terminology (a plan id, a spec section) that does
64
+ * not belong in the user-facing `message`.
65
+ */
66
+ internalRef?: string;
67
+ [key: string]: unknown;
68
+ }
69
+ /** The error arm's payload. */
70
+ export interface IOutcomeError {
71
+ code: BacklogErrorCode;
72
+ message: string;
73
+ details?: IOutcomeErrorDetails;
74
+ }
75
+ /**
76
+ * Pagination truth carried beside the data. `total` is the count BEFORE
77
+ * `limit`/`offset`; `returned` is `data.length`. A silently-truncated list is
78
+ * indistinguishable from a complete one unless the envelope says how many
79
+ * there really were.
80
+ */
81
+ export interface IQueryEnvelopeMeta {
82
+ /** Matching rows before limit/offset — the TRUE count. */
83
+ total: number;
84
+ /** Rows actually in `data`. */
85
+ returned: number;
86
+ limit?: number;
87
+ offset?: number;
88
+ /**
89
+ * Set when the result set was cut short by anything other than the caller's
90
+ * own `limit`. A silent cap is forbidden — if it happens, it is stated here.
91
+ */
92
+ truncated?: boolean;
93
+ }
94
+ /** The success arm. `data` is always present (never `null` as a stand-in for "missing"). */
95
+ export interface IOutcomeSuccess<T> {
96
+ ok: true;
97
+ data: T;
98
+ /** Non-fatal ambiguity surfaced at resolution time. A read NEVER silently narrows. */
99
+ warnings?: string[];
100
+ /** Present on list-shaped reads. */
101
+ meta?: IQueryEnvelopeMeta;
102
+ }
103
+ /** The failure arm. There is no `data` on this arm at all. */
104
+ export interface IOutcomeFailure {
105
+ ok: false;
106
+ error: IOutcomeError;
107
+ warnings?: string[];
108
+ }
109
+ /**
110
+ * THE response envelope for every mounted verb.
111
+ *
112
+ * A `void`/`null` return is rendered by apigen as `{"result": null}` for BOTH
113
+ * success and failure, which makes a write unverifiable. This union has no arm
114
+ * that can express that: success carries `data`, failure carries `error`, and
115
+ * `ok` discriminates them.
116
+ *
117
+ * It is a discriminated union rather than `{ ok, data?, error? }` on purpose —
118
+ * `{ ok: true, data: null }` for a missing item is not assignable when `T` is
119
+ * a real item type.
120
+ */
121
+ export type IOutcomeEnvelope<T> = IOutcomeSuccess<T> | IOutcomeFailure;
122
+ /** Narrow an envelope to its success arm. */
123
+ export declare function isOutcomeOk<T>(env: IOutcomeEnvelope<T>): env is IOutcomeSuccess<T>;
124
+ /**
125
+ * Narrow an envelope to its failure arm.
126
+ *
127
+ * Deliberately structural (`ok === false` AND a well-formed `error`) — a
128
+ * malformed half-envelope is neither ok nor a usable error, and callers must
129
+ * not treat it as success by accident.
130
+ */
131
+ export declare function isOutcomeError<T>(env: IOutcomeEnvelope<T>): env is IOutcomeFailure;
132
+ /** Build a success envelope. */
133
+ export declare function okEnvelope<T>(data: T, extra?: {
134
+ warnings?: string[];
135
+ meta?: IQueryEnvelopeMeta;
136
+ }): IOutcomeSuccess<T>;
137
+ /** Build a failure envelope. `store_busy` is stamped retryable by default. */
138
+ export declare function errorEnvelope(code: BacklogErrorCode, message: string, details?: IOutcomeErrorDetails): IOutcomeFailure;
139
+ /** The process exit code a CLI host must use for an envelope. Success is always 0. */
140
+ export declare function exitCodeForEnvelope<T>(env: IOutcomeEnvelope<T>): number;
141
+ /**
142
+ * Structural guard for a value that came back from a transport, where the
143
+ * static type is erased. Recognises BOTH arms.
144
+ *
145
+ * Used by the CLI's `options.exitCode` hook — a non-envelope result (a `--use`
146
+ * mount, a plugin's own synthetic op) must fall through to apigen's default
147
+ * exit-0-on-return, never be mapped by this table.
148
+ */
149
+ export declare function isOutcomeEnvelope(value: unknown): value is IOutcomeEnvelope<unknown>;
150
+ /** Why a similarity-ranked read cannot be served. */
151
+ export type RagUnavailableReason = 'not_configured' | 'empty_vector_space';
152
+ /**
153
+ * A similarity-ranked read was requested but cannot be served.
154
+ *
155
+ * Distinguishes "no backend at all" from "a backend exists but nothing has
156
+ * been embedded yet" — an unbackfilled space would otherwise return an empty
157
+ * result set, which reads as "no matches" when the truth is "this ranking is
158
+ * not available." Reporting it as disabled is the honest answer.
159
+ */
160
+ export declare class RagNotConfiguredError extends Error {
161
+ readonly reason: RagUnavailableReason;
162
+ constructor(feature: string, reason?: RagUnavailableReason);
163
+ }
package/index.d.ts CHANGED
@@ -1,17 +1,18 @@
1
- export { addCitation, addDependency, appendNote, archiveResolved, assignItem, attachToPlan, auditTrail, blockers, claimItem, createItem, dependencyGraph, exportJson, getItem, importFromMarkdown, linkRelated, listItems, mergeItems, migrationStatus, readyItems, releaseClaim, removeDependency, renderToMarkdown, renewClaim, resolveItem, setMigrationPhase, setPriority, softDeleteItem, spotlight, splitItem, staleClaims, startWork, stats, supersedeItem, topoOrder, transitionStatus, updateItem, version, } from './client.js';
2
- export type { BacklogCtx, BacklogVersionInfo } from './client.js';
3
- export { startBacklogServer, buildBacklogApigenPackage } from './server.js';
1
+ export { get, query, priorityMatrix, partOfRollup, openCurve, lookup, create, update, transition, claim, relate, move, upsertProject, upsertComponent, upsertLocation, rmLocation, delete, } from './api.js';
2
+ export type { BacklogCtx } from './api.js';
3
+ export * from './envelope.js';
4
+ export { startBacklogServer, buildBacklogApigenPackage, resolveExpectedMcpToolNames, } from './server.js';
4
5
  export type { StartOpts } from './server.js';
5
- export { runBacklogCli, resolveCommandPrefix, prefixCommand } from './cli.js';
6
+ export { runBacklogCli, resolveCommandPrefix, prefixCommand, stripNamespaceFlag, } from './cli.js';
6
7
  export type { RunBacklogCliOpts } from './cli.js';
8
+ export { buildSearchArgv, SEARCH_FLAGS, SEARCH_HELP, } from './search-shortcut.js';
9
+ export type { SearchShortcutOutcome } from './search-shortcut.js';
7
10
  export { installSkill, runInstallSkillCommand } from './install-skill.js';
8
- export type { InstallSkillResult, SkillHost, SkillScope } from './install-skill.js';
11
+ export type { InstallSkillResult, SkillHost, SkillScope, } from './install-skill.js';
9
12
  export { runServeCommand } from './serve.js';
10
13
  export type { RunServeCommandOpts } from './serve.js';
11
- export { buildBacklogEnv, resolveBacklogScope, resolveBacklogDbPath, suggestClaimantIdentity, backlogEnvironmentSpec } from './env.js';
14
+ export { buildBacklogEnv, resolveBacklogScope, resolveBacklogDbPath, suggestClaimantIdentity, backlogEnvironmentSpec, } from './env.js';
12
15
  export type { BacklogConfig, BuildBacklogEnvOptions } from './env.js';
13
- export { openGraphBacklogStore, closeGraphBacklogStore } from './store/graph-backlog-store.js';
16
+ export { openGraphBacklogStore, closeGraphBacklogStore, } from './store/graph-backlog-store.js';
14
17
  export type { GraphBacklogStore } from './store/graph-backlog-store.js';
15
- export { buildChangelogSection, classifyStatus, detectPriority, detectStatus, normalizeLegacyStatus, parseBacklogMarkdown, parseBacklogMarkdownWithDiagnostics, renderItemsToMarkdown, toImportItems, } from './markdown.js';
16
- export type { ParsedImportItem, ParsedMarkdownItem, ParseWithDiagnosticsResult } from './markdown.js';
17
- export * from './model.js';
18
+ export { readBacklogVersionInfo } from './version-info.js';