@dev-loops/core 1.0.0-rc.2 → 1.0.0-rc.3

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.
@@ -0,0 +1,50 @@
1
+ export { createTrackerAdapter, isTrackerAdapter, hasBoardCapability, REQUIRED_METHODS, BOARD_METHODS } from "./adapter.mjs";
2
+ export { createGithubTrackerAdapter } from "./github-adapter.mjs";
3
+ export { createNoopTrackerAdapter } from "./noop-adapter.mjs";
4
+
5
+ import { createGithubTrackerAdapter } from "./github-adapter.mjs";
6
+
7
+ /** Built-in provider registry — GitHub is the only baked-in provider in v1
8
+ * (issue #1408); an external provider registers here post-1.0 (or a consumer
9
+ * passes its own adapter directly, bypassing this registry entirely). */
10
+ const BUILTIN_PROVIDERS = Object.freeze({
11
+ github: createGithubTrackerAdapter,
12
+ });
13
+
14
+ /**
15
+ * Resolve the tracker adapter for the given effective dev-loop config.
16
+ *
17
+ * Config-driven with NO global/singleton state (#1408 design constraint): a
18
+ * future multi-tracker or per-capability layer just calls this again with a
19
+ * different scoped config, and it stays additive — this function never reads
20
+ * outside its `config` argument.
21
+ *
22
+ * `config?.tracker?.provider` selects a provider FROM THE REGISTERED
23
+ * `providers` map (default `"github"`, the only one registered out of the
24
+ * box) — the registry is extensible, not built-in-only: a consumer passes
25
+ * `{ providers: { ...builtins, jira: createJiraAdapter } }` to register an
26
+ * external provider (post-1.0 consumer concern). An unknown provider (not in
27
+ * whatever `providers` was actually passed) fails closed rather than
28
+ * silently falling back to GitHub. `config?.tracker?.plugin` is reserved for
29
+ * a consumer's own module-loading resolver in front of this — not
30
+ * implemented in this pass (non-goal, #1408).
31
+ *
32
+ * @param {import("../config/config.mjs").DevLoopConfig|null|undefined} config
33
+ * @param {{ env?: NodeJS.ProcessEnv, ghCommand?: string, providers?: Record<string, Function> }} [deps]
34
+ * @returns {import("./adapter.mjs").TrackerAdapter}
35
+ */
36
+ export function resolveTrackerAdapter(config, { env, ghCommand, providers = BUILTIN_PROVIDERS } = {}) {
37
+ const provider = config?.tracker?.provider?.trim() || "github";
38
+ const factory = providers[provider];
39
+ if (typeof factory !== "function") {
40
+ throw new Error(
41
+ `Unknown tracker.provider "${provider}" — no adapter is registered for it. ` +
42
+ `Registered: ${Object.keys(providers).join(", ")} ("github" is the built-in default; ` +
43
+ `any others listed here were registered by the caller). ` +
44
+ `An external provider is a post-1.0 consumer concern: register it by passing ` +
45
+ `{ providers: { ...builtins, "${provider}": createYourAdapter } } to resolveTrackerAdapter ` +
46
+ `(setting tracker.provider in .devloops alone does not register one).`,
47
+ );
48
+ }
49
+ return factory({ ...(env !== undefined ? { env } : {}), ...(ghCommand !== undefined ? { ghCommand } : {}) });
50
+ }
@@ -0,0 +1,35 @@
1
+ import { createTrackerAdapter } from "./adapter.mjs";
2
+
3
+ /**
4
+ * Create a minimal, in-memory tracker adapter for tests. Every Issues method
5
+ * is a deterministic stub; Board methods are included so tests can also
6
+ * exercise the optional capability without a real GitHub Projects board.
7
+ *
8
+ * @param {Partial<import("./adapter.mjs").TrackerAdapter>} [overrides]
9
+ * @returns {import("./adapter.mjs").TrackerAdapter}
10
+ */
11
+ export function createNoopTrackerAdapter(overrides = {}) {
12
+ return createTrackerAdapter({
13
+ parseRef: (urlOrRef) => ({ repo: "", id: String(urlOrRef) }),
14
+ getIssue: async (ref) => ({
15
+ id: ref?.id ?? "",
16
+ title: "",
17
+ body: "",
18
+ url: "",
19
+ state: "open",
20
+ assignees: [],
21
+ }),
22
+ createIssue: async () => ({ id: "0", url: "" }),
23
+ editIssue: async () => ({ edited: [] }),
24
+ commentIssue: async () => ({ commentUrl: "" }),
25
+ listIssues: async () => [],
26
+ detectLinkedPr: async () => null,
27
+ ensureBoard: async () => ({}),
28
+ listQueueItems: async () => [],
29
+ addQueueItem: async () => ({}),
30
+ setItemStatus: async () => {},
31
+ reorderItem: async () => {},
32
+ archiveItems: async () => {},
33
+ ...overrides,
34
+ });
35
+ }