@adhd/backlog 0.0.1 β 0.1.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.
- package/CHANGELOG.md +53 -0
- package/README.md +40 -4
- package/cli.d.ts +71 -0
- package/client.d.ts +42 -2
- package/env.d.ts +4 -0
- package/index.d.ts +9 -3
- package/index.js +172 -160
- package/index.mjs +15027 -12368
- package/install-skill.d.ts +28 -0
- package/markdown.d.ts +12 -1
- package/migration-admin.d.ts +26 -0
- package/model.d.ts +93 -0
- package/package.json +15 -7
- package/serve.d.ts +12 -0
- package/server.d.ts +50 -3
- package/store/audit-log.d.ts +16 -0
- package/store/crud.d.ts +13 -6
- package/store/graph-backlog-store.d.ts +10 -1
- package/store/ids.d.ts +21 -0
- package/store/immediate-retry.d.ts +27 -0
- package/store/mapping.d.ts +52 -0
package/CHANGELOG.md
CHANGED
|
@@ -1 +1,54 @@
|
|
|
1
|
+
## 0.0.3 (2026-07-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### π©Ή Fixes
|
|
5
|
+
|
|
6
|
+
- **apigen,backlog:** killable serve, configurable namespace, flaky test + log spam
|
|
7
|
+
|
|
8
|
+
- **backlog:** match archived-item exclusion between render and its verify
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### β€οΈ Thank You
|
|
12
|
+
|
|
13
|
+
- pseudosky
|
|
14
|
+
|
|
15
|
+
## 0.0.2 (2026-07-24)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### π Features
|
|
19
|
+
|
|
20
|
+
- **backlog:** add CLI entrypoint + bin (live apigen cli-output mount)
|
|
21
|
+
|
|
22
|
+
- **backlog:** add migration.phase signal + migrationStatus op (MIGRATION.md Β§4.4)
|
|
23
|
+
|
|
24
|
+
- **backlog:** Phase 1/2 apigen import + CI parity gate + durable migration.phase admin write
|
|
25
|
+
|
|
26
|
+
- **backlog:** author backlog-usage skill + install-skill CLI (MIGRATION.md sec 4.2/4.3)
|
|
27
|
+
|
|
28
|
+
- **backlog:** add `serve` CLI command so .mcp.json has a real entry to spawn (MIGRATION.md sec 4.5)
|
|
29
|
+
|
|
30
|
+
- **backlog:** rootLevel projection filter so new tool items reach root
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### π©Ή Fixes
|
|
34
|
+
|
|
35
|
+
- **backlog:** close Phase-3 migration gate β CI Node floor, content-hash collision verified, FTS content immutability, bounded busy-retry; plus import provenance/silent-drop fixes
|
|
36
|
+
|
|
37
|
+
- **backlog:** runBacklogCli no longer eagerly opens the store for --help/no-args (DEBT-BACKLOG-CLI-EAGER-STORE-OPEN-001)
|
|
38
|
+
|
|
39
|
+
- **backlog:** concurrent createItem id-collision + FTS sanitizer gap (MIGRATION.md sec 3.3 scale test)
|
|
40
|
+
|
|
41
|
+
- **backlog:** implement real transition/claim audit-log (DEBT-BACKLOG-AUDIT-TRAIL-PARTIAL-001)
|
|
42
|
+
|
|
43
|
+
- **backlog:** importFromMarkdown upserts on re-import instead of insert-only
|
|
44
|
+
|
|
45
|
+
- **backlog:** sourcepath-ownership gate for importFromMarkdown (DEBT-BACKLOG-IMPORT-SCOPE-CROSSFILE-001)
|
|
46
|
+
|
|
47
|
+
- **backlog:** re-import backfills ownership + resurrects superseded ids
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### β€οΈ Thank You
|
|
51
|
+
|
|
52
|
+
- pseudosky
|
|
53
|
+
|
|
1
54
|
## Unreleased
|
package/README.md
CHANGED
|
@@ -54,10 +54,46 @@ const abort = new AbortController();
|
|
|
54
54
|
await startBacklogServer({ transport: 'both', port: 3400, signal: abort.signal });
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
- `POST /backlog/
|
|
58
|
-
export, mounted live via `@adhd/apigen-plugin-api-fastify`.
|
|
59
|
-
-
|
|
60
|
-
|
|
57
|
+
- `POST /backlog/client-d/create-item`, `GET /backlog/client-d/get-item`, ... β
|
|
58
|
+
every `client.ts` export, mounted live via `@adhd/apigen-plugin-api-fastify`.
|
|
59
|
+
(The `client-d` route segment is not a typo β see `DESIGN.md` Β§7's CLI
|
|
60
|
+
section / `SPEC.md` Β§7's transport table for why it's there.)
|
|
61
|
+
- Every export is also available as an MCP tool (e.g. `backlog_client_d_get_item`)
|
|
62
|
+
via `@adhd/apigen-plugin-mcp` (stdio transport by default).
|
|
63
|
+
|
|
64
|
+
## CLI (`backlog`, live apigen mount β no codegen)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm add -g @adhd/backlog # installs the `backlog` bin
|
|
68
|
+
backlog --help # live-derived command listing
|
|
69
|
+
backlog create-item --input '{"family":"BUG-EXAMPLE","title":"t","body":"b","repo":"org/repo"}'
|
|
70
|
+
backlog get-item --repo org/repo --human-id BUG-EXAMPLE-001
|
|
71
|
+
backlog list-items --filter '{"status":"OPEN"}'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- Same architecture as the HTTP/MCP transports above β `entrypoint/backlog/src/cli.ts`'s
|
|
75
|
+
`runBacklogCli()` reuses `buildBacklogApigenPackage()` and hands it straight
|
|
76
|
+
to `@adhd/apigen-plugin-cli-output`'s `run()`. No `apigen generate`, no
|
|
77
|
+
bespoke argument parsing β routing, flag parsing, validation, dispatch, and
|
|
78
|
+
exit codes all come from that plugin.
|
|
79
|
+
- **You type `backlog <command>`, never the internal `client-d` segment.**
|
|
80
|
+
`runBacklogCli` derives the real command-table prefix from the live
|
|
81
|
+
`operations` list at runtime (`resolveCommandPrefix`) and prepends it before
|
|
82
|
+
dispatch β so `backlog get-item β¦` resolves even though the plugin's real
|
|
83
|
+
command table is keyed `backlog client-d get-item` internally (same
|
|
84
|
+
`client-d` artifact as the HTTP/MCP routes above; the CLI is the one
|
|
85
|
+
transport that hides it from the caller).
|
|
86
|
+
- Flags are the schema's domain params, kebab-cased (`humanId` β `--human-id`);
|
|
87
|
+
object/array-typed params take a JSON string (`--input '{...}'`,
|
|
88
|
+
`--filter '{...}'`).
|
|
89
|
+
- Exit codes follow `@adhd/apigen-base-errors`'s `CLI_EXIT_CODE` table: `0`
|
|
90
|
+
success, `2` invalid argument (bad/unknown flag, failed validation), `4`
|
|
91
|
+
unknown command, etc. Result is printed as JSON to stdout; errors as JSON to
|
|
92
|
+
stderr.
|
|
93
|
+
- Honors the same `ADHD_BACKLOG_SCOPE`/`ADHD_ENV_SCOPE` scope env vars as the
|
|
94
|
+
library API (see Scope below) β there is no separate CLI-only config.
|
|
95
|
+
- `runBacklogCli(argv?, opts?)` is also exported for in-process programmatic
|
|
96
|
+
use (e.g. a test harness), symmetric with `startBacklogServer`.
|
|
61
97
|
|
|
62
98
|
## Scope
|
|
63
99
|
|
package/cli.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Operation } from '@adhd/apigen-core-client';
|
|
2
|
+
import { Scope } from '@adhd/environment-base-spec';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Derives the internal command-path PREFIX every `client.ts` operation
|
|
6
|
+
* shares in `@adhd/apigen-plugin-cli-output`'s command table
|
|
7
|
+
* (`buildCommandTable()`: `cliPath = project(op).cli.path`, and
|
|
8
|
+
* `project()`'s `cli.path = [namespace, ...path].map(toKebab)` β
|
|
9
|
+
* `@adhd/apigen-engine-naming`'s `naming.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Currently simply `['backlog']`: `server.ts`'s `extractClientOperations()`
|
|
12
|
+
* calls `extract({ β¦, dropFileSegment: true })`, so every `client.ts`
|
|
13
|
+
* export's `path` is just `[exportSegment]` (no `client.d.ts`-derived
|
|
14
|
+
* `'client-d'` segment β see that call site's doc comment for why it's safe
|
|
15
|
+
* to drop here: one source file, no cross-file names to disambiguate), and
|
|
16
|
+
* `project(op).cli.path` is `['backlog', '<kebab-export-name>']`.
|
|
17
|
+
*
|
|
18
|
+
* This is still derived from the live `operations` list rather than
|
|
19
|
+
* hardcoded, on purpose: since every `client.ts` export shares the same
|
|
20
|
+
* namespace + same source, every operation's `cli.path` differs ONLY in its
|
|
21
|
+
* final (export) segment, so the shared prefix is simply "everything but the
|
|
22
|
+
* last segment" of any one operation's projected `cli.path`. Computed fresh
|
|
23
|
+
* on every call (never cached as a literal) so a future change to the
|
|
24
|
+
* extraction call site (e.g. re-enabling the file segment, or adding a
|
|
25
|
+
* second source file) can never silently desync this from the real command
|
|
26
|
+
* table the way a hardcoded `['backlog']` constant would.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveCommandPrefix(operations: readonly Operation[]): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Prepends `prefix` (the real, namespace-qualified command path segments
|
|
31
|
+
* every `client.ts` export shares β see {@link resolveCommandPrefix}) to a
|
|
32
|
+
* user-typed argv, so `backlog get-item --repo β¦ --human-id β¦` (what a
|
|
33
|
+
* consumer actually types β the bin's own name is never part of `argv`)
|
|
34
|
+
* resolves against the cli-output plugin's command table, which is keyed by
|
|
35
|
+
* the FULL internal path (`['backlog', 'get-item']`).
|
|
36
|
+
*
|
|
37
|
+
* Idempotent / defensive:
|
|
38
|
+
* - Empty argv is returned unchanged β `run()` treats `argv.length === 0`
|
|
39
|
+
* as the usage listing regardless of any prefix.
|
|
40
|
+
* - Argv already starting with the full `prefix` (in order) is returned
|
|
41
|
+
* unchanged β never double-prefixed.
|
|
42
|
+
* - A leading flag (`--help`, `-h`, or any other top-level `-`-prefixed
|
|
43
|
+
* token) is returned unchanged β `run()` special-cases `--help`/`-h`
|
|
44
|
+
* BEFORE ever consulting the command table
|
|
45
|
+
* (`if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h')`),
|
|
46
|
+
* so prefixing here would shadow that check and break `backlog --help`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function prefixCommand(userArgv: readonly string[], prefix: readonly string[]): string[];
|
|
49
|
+
export interface RunBacklogCliOpts {
|
|
50
|
+
scope?: Scope;
|
|
51
|
+
/** Test-only override β see `buildBacklogEnv`'s `BuildBacklogEnvOptions`. */
|
|
52
|
+
adhdRoot?: string;
|
|
53
|
+
cwd?: string;
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Opens (or reuses) the backlog store + env, then dispatches EXACTLY ONE CLI
|
|
58
|
+
* command live through `@adhd/apigen-plugin-cli-output`'s `run()` β no code
|
|
59
|
+
* generation, no bespoke argument parsing. Mirrors `startBacklogServer`'s
|
|
60
|
+
* envβstoreβctxβ`buildBacklogApigenPackage` setup precisely; the only
|
|
61
|
+
* divergence is transport-specific: `cliPlugin.run()` is one-shot (it
|
|
62
|
+
* resolves after dispatching a single command rather than listening), so
|
|
63
|
+
* there is no `Promise.all` of long-lived transports to await here.
|
|
64
|
+
*
|
|
65
|
+
* @param argv Command + flags, WITHOUT the `backlog` bin name (e.g.
|
|
66
|
+
* `['get-item', '--repo', 'org/repo', '--human-id', 'BUG-1']`). Defaults
|
|
67
|
+
* to `process.argv.slice(2)` β the real CLI invocation's own argv β when
|
|
68
|
+
* omitted, matching `cliPlugin.run()`'s own `resolveArgv()` fallback
|
|
69
|
+
* convention.
|
|
70
|
+
*/
|
|
71
|
+
export declare function runBacklogCli(argv?: string[], opts?: RunBacklogCliOpts): Promise<void>;
|
package/client.d.ts
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { GraphBacklogStore } from './store/graph-backlog-store.js';
|
|
2
2
|
import { BacklogConfig } from './env.js';
|
|
3
|
-
import { ArchiveOpts, ArchiveResult, AuditTrailResult, BacklogFilter, BacklogItem, BacklogStats, BacklogStatus, ClaimOpts, ClaimResult, Citation, CreateItemInput, CreateItemResult, DependencyGraph, ImportMarkdownInput, ImportResult, Priority, ReleaseResult, StatsScope, TopoOrderResult, TransitionOpts, UpdateItemInput } from './model.js';
|
|
3
|
+
import { ArchiveOpts, ArchiveResult, AuditTrailResult, BacklogFilter, BacklogItem, BacklogStats, BacklogStatus, ClaimOpts, ClaimResult, Citation, CreateItemInput, CreateItemResult, DependencyGraph, ImportMarkdownInput, ImportResult, MigrationPhase, MigrationStatusResult, Priority, ReleaseResult, SetMigrationPhaseResult, StatsScope, TopoOrderResult, TransitionOpts, UpdateItemInput } from './model.js';
|
|
4
4
|
import { Environment } from '@adhd/environment';
|
|
5
5
|
|
|
6
6
|
/** The one type apigen special-cases via the `ctx-name-only` invariant. */
|
|
7
7
|
export interface BacklogCtx {
|
|
8
8
|
store: GraphBacklogStore;
|
|
9
9
|
env: Environment<BacklogConfig>;
|
|
10
|
+
/**
|
|
11
|
+
* Test-isolation escape hatch ONLY β mirrors `BuildBacklogEnvOptions.adhdRoot`
|
|
12
|
+
* (the same value passed to `buildBacklogEnv({ adhdRoot })` when constructing
|
|
13
|
+
* `env`). NEVER set this in production code (`server.ts`/`cli.ts` never do).
|
|
14
|
+
* `setMigrationPhase` threads it through to `writeMigrationPhase` so a
|
|
15
|
+
* temp-rooted test `ctx` can never write to the real machine-global
|
|
16
|
+
* `~/.adhd` β omitting this on a real ctx write is exactly the bug
|
|
17
|
+
* `migration-admin.spec.ts`'s negative control caught (a test run wrote
|
|
18
|
+
* `phase-4` to the real `~/.adhd/backlog/production/config.yaml` before
|
|
19
|
+
* this field existed; reverted, see CHANGELOG).
|
|
20
|
+
*/
|
|
21
|
+
adhdRoot?: string;
|
|
10
22
|
}
|
|
11
23
|
/**
|
|
12
24
|
* Dedupe-scans (FTS + symbol/path/errorText metadata match) before writing.
|
|
@@ -65,8 +77,36 @@ export declare function setPriority(ctx: BacklogCtx, repo: string, humanId: stri
|
|
|
65
77
|
/** MEMBER_OF edge to a plan node (auto-created if the plan slug hasn't been seen before). */
|
|
66
78
|
export declare function attachToPlan(ctx: BacklogCtx, repo: string, humanId: string, planSlug: string): Promise<void>;
|
|
67
79
|
export declare function importFromMarkdown(ctx: BacklogCtx, input: ImportMarkdownInput): Promise<ImportResult>;
|
|
68
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* Excludes archived items (SPEC.md Β§5.4 archiveResolved) β see markdown.ts's
|
|
82
|
+
* renderItemsToMarkdown doc comment. Archival exclusion goes through
|
|
83
|
+
* `BacklogFilter.excludeArchived` (query.ts's `applyExcludeArchivedFilter`)
|
|
84
|
+
* rather than a private scan here, so a caller comparing this output
|
|
85
|
+
* against `listItems`/`queryItemNodes` for the SAME filter (e.g.
|
|
86
|
+
* `render-projections.mjs`'s round-trip verify) can reproduce this exact
|
|
87
|
+
* item set by passing `{ ...filter, excludeArchived: true }` themselves β
|
|
88
|
+
* see BUG-BACKLOG-RENDER-VERIFY-ARCHIVED-MISMATCH-001.
|
|
89
|
+
*/
|
|
69
90
|
export declare function renderToMarkdown(ctx: BacklogCtx, filter?: BacklogFilter): Promise<string>;
|
|
70
91
|
export declare function exportJson(ctx: BacklogCtx, filter?: BacklogFilter): Promise<BacklogItem[]>;
|
|
71
92
|
/** Bi-temporal history + supersession chain. */
|
|
72
93
|
export declare function auditTrail(ctx: BacklogCtx, repo: string, humanId: string): Promise<AuditTrailResult>;
|
|
94
|
+
/**
|
|
95
|
+
* MIGRATION.md Β§4.4 β a QUERIED signal, never hardcoded prose: reports the
|
|
96
|
+
* live `migration.phase` config value (`env.ts`, env-overridable via
|
|
97
|
+
* `ADHD_BACKLOG_MIGRATION_PHASE`) plus a human-readable meaning, so an agent
|
|
98
|
+
* (or the `backlog-usage` skill) always asks the tool which of BACKLOG.md or
|
|
99
|
+
* the tool is authoritative right now, instead of trusting a stale doc
|
|
100
|
+
* sentence. NOT yet per-repo-keyed (MIGRATION.md Β§9 open decision 6) β one
|
|
101
|
+
* global value for the whole machine.
|
|
102
|
+
*/
|
|
103
|
+
export declare function migrationStatus(ctx: BacklogCtx): Promise<MigrationStatusResult>;
|
|
104
|
+
/**
|
|
105
|
+
* MIGRATION.md Β§4.4's "admin CLI call" half: writes `migration.phase`
|
|
106
|
+
* THROUGH to the GLOBAL layer's `config.yaml` (`migration-admin.ts`) so the
|
|
107
|
+
* new value is a durable, cross-process, cross-repo signal β not merely an
|
|
108
|
+
* env var scoped to whoever's shell happened to export it. Whoever executes
|
|
109
|
+
* a phase's Definition of Done calls this exactly once, after verifying the
|
|
110
|
+
* DoD, never speculatively.
|
|
111
|
+
*/
|
|
112
|
+
export declare function setMigrationPhase(ctx: BacklogCtx, phase: MigrationPhase): Promise<SetMigrationPhaseResult>;
|
package/env.d.ts
CHANGED
|
@@ -4,10 +4,14 @@ import { Environment } from '@adhd/environment';
|
|
|
4
4
|
export interface BacklogConfig {
|
|
5
5
|
readonly db: {
|
|
6
6
|
readonly path: string | undefined;
|
|
7
|
+
readonly busyTimeoutMs: number;
|
|
7
8
|
};
|
|
8
9
|
readonly logging: {
|
|
9
10
|
readonly level: string;
|
|
10
11
|
};
|
|
12
|
+
readonly migration: {
|
|
13
|
+
readonly phase: string;
|
|
14
|
+
};
|
|
11
15
|
}
|
|
12
16
|
export declare const backlogEnvironmentSpec: EnvironmentSpec<BacklogConfig>;
|
|
13
17
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
export { addCitation, addDependency, appendNote, archiveResolved, assignItem, attachToPlan, auditTrail, blockers, claimItem, createItem, dependencyGraph, exportJson, getItem, importFromMarkdown, linkRelated, listItems, mergeItems, readyItems, releaseClaim, removeDependency, renderToMarkdown, renewClaim, resolveItem, setPriority, softDeleteItem, spotlight, splitItem, staleClaims, startWork, stats, supersedeItem, topoOrder, transitionStatus, updateItem, } from './client.js';
|
|
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, } from './client.js';
|
|
2
2
|
export type { BacklogCtx } from './client.js';
|
|
3
3
|
export { startBacklogServer, buildBacklogApigenPackage } from './server.js';
|
|
4
4
|
export type { StartOpts } from './server.js';
|
|
5
|
+
export { runBacklogCli, resolveCommandPrefix, prefixCommand } from './cli.js';
|
|
6
|
+
export type { RunBacklogCliOpts } from './cli.js';
|
|
7
|
+
export { installSkill, runInstallSkillCommand } from './install-skill.js';
|
|
8
|
+
export type { InstallSkillResult, SkillHost, SkillScope } from './install-skill.js';
|
|
9
|
+
export { runServeCommand } from './serve.js';
|
|
10
|
+
export type { RunServeCommandOpts } from './serve.js';
|
|
5
11
|
export { buildBacklogEnv, resolveBacklogScope, suggestClaimantIdentity, backlogEnvironmentSpec } from './env.js';
|
|
6
12
|
export type { BacklogConfig, BuildBacklogEnvOptions } from './env.js';
|
|
7
13
|
export { openGraphBacklogStore, closeGraphBacklogStore } from './store/graph-backlog-store.js';
|
|
8
14
|
export type { GraphBacklogStore } from './store/graph-backlog-store.js';
|
|
9
|
-
export { buildChangelogSection, classifyStatus, detectPriority, detectStatus, normalizeLegacyStatus, parseBacklogMarkdown, renderItemsToMarkdown, toImportItems, } from './markdown.js';
|
|
10
|
-
export type { ParsedImportItem, ParsedMarkdownItem } from './markdown.js';
|
|
15
|
+
export { buildChangelogSection, classifyStatus, detectPriority, detectStatus, normalizeLegacyStatus, parseBacklogMarkdown, parseBacklogMarkdownWithDiagnostics, renderItemsToMarkdown, toImportItems, } from './markdown.js';
|
|
16
|
+
export type { ParsedImportItem, ParsedMarkdownItem, ParseWithDiagnosticsResult } from './markdown.js';
|
|
11
17
|
export * from './model.js';
|