@codified/cli 0.3.5 → 0.3.7

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 (106) hide show
  1. package/README.md +115 -0
  2. package/dist/commands/add.d.ts +3 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +163 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/bootstrap.d.ts.map +1 -0
  7. package/dist/commands/bootstrap.js +141 -0
  8. package/dist/commands/bootstrap.js.map +1 -0
  9. package/dist/commands/check.d.ts +3 -0
  10. package/dist/commands/check.d.ts.map +1 -0
  11. package/dist/commands/check.js +332 -0
  12. package/dist/commands/check.js.map +1 -0
  13. package/dist/commands/cleanup.d.ts +3 -0
  14. package/dist/commands/cleanup.d.ts.map +1 -0
  15. package/dist/commands/cleanup.js +166 -0
  16. package/dist/commands/cleanup.js.map +1 -0
  17. package/dist/commands/collect.d.ts +26 -0
  18. package/dist/commands/collect.d.ts.map +1 -0
  19. package/dist/commands/collect.js +269 -0
  20. package/dist/commands/collect.js.map +1 -0
  21. package/dist/commands/connect.d.ts +3 -0
  22. package/dist/commands/connect.d.ts.map +1 -0
  23. package/dist/commands/connect.js +321 -0
  24. package/dist/commands/connect.js.map +1 -0
  25. package/dist/commands/explain.d.ts +3 -0
  26. package/dist/commands/explain.d.ts.map +1 -0
  27. package/dist/commands/explain.js +527 -0
  28. package/dist/commands/explain.js.map +1 -0
  29. package/dist/commands/export.d.ts +3 -0
  30. package/dist/commands/export.d.ts.map +1 -0
  31. package/dist/commands/export.js +59 -0
  32. package/dist/commands/export.js.map +1 -0
  33. package/dist/commands/gaps.d.ts +3 -0
  34. package/dist/commands/gaps.d.ts.map +1 -0
  35. package/dist/commands/gaps.js +315 -0
  36. package/dist/commands/gaps.js.map +1 -0
  37. package/dist/commands/graph.d.ts +3 -0
  38. package/dist/commands/graph.d.ts.map +1 -0
  39. package/dist/commands/graph.js +293 -0
  40. package/dist/commands/graph.js.map +1 -0
  41. package/dist/commands/import-cmd.d.ts +3 -0
  42. package/dist/commands/import-cmd.d.ts.map +1 -0
  43. package/dist/commands/import-cmd.js +199 -0
  44. package/dist/commands/import-cmd.js.map +1 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +215 -0
  47. package/dist/commands/init.js.map +1 -0
  48. package/dist/commands/project.d.ts +3 -0
  49. package/dist/commands/project.d.ts.map +1 -0
  50. package/dist/commands/project.js +179 -0
  51. package/dist/commands/project.js.map +1 -0
  52. package/dist/commands/reset.d.ts +3 -0
  53. package/dist/commands/reset.d.ts.map +1 -0
  54. package/dist/commands/reset.js +157 -0
  55. package/dist/commands/reset.js.map +1 -0
  56. package/dist/commands/search.d.ts +3 -0
  57. package/dist/commands/search.d.ts.map +1 -0
  58. package/dist/commands/search.js +183 -0
  59. package/dist/commands/search.js.map +1 -0
  60. package/dist/commands/start.d.ts.map +1 -0
  61. package/dist/commands/start.js +205 -0
  62. package/dist/commands/start.js.map +1 -0
  63. package/dist/commands/status.d.ts.map +1 -0
  64. package/dist/commands/status.js +242 -0
  65. package/dist/commands/status.js.map +1 -0
  66. package/dist/commands/timeline.d.ts +3 -0
  67. package/dist/commands/timeline.d.ts.map +1 -0
  68. package/dist/commands/timeline.js +424 -0
  69. package/dist/commands/timeline.js.map +1 -0
  70. package/dist/commands/triage.d.ts +3 -0
  71. package/dist/commands/triage.d.ts.map +1 -0
  72. package/dist/commands/triage.js +336 -0
  73. package/dist/commands/triage.js.map +1 -0
  74. package/dist/commands/up.d.ts +3 -0
  75. package/dist/commands/up.d.ts.map +1 -0
  76. package/dist/commands/up.js +312 -0
  77. package/dist/commands/up.js.map +1 -0
  78. package/dist/commands/watch.d.ts +3 -0
  79. package/dist/commands/watch.d.ts.map +1 -0
  80. package/dist/commands/watch.js +224 -0
  81. package/dist/commands/watch.js.map +1 -0
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +636 -506
  85. package/dist/index.js.map +1 -0
  86. package/dist/lib/config.d.ts +52 -0
  87. package/dist/lib/config.d.ts.map +1 -0
  88. package/dist/lib/config.js +142 -0
  89. package/dist/lib/config.js.map +1 -0
  90. package/dist/lib/docker.d.ts +23 -0
  91. package/dist/lib/docker.d.ts.map +1 -0
  92. package/dist/lib/docker.js +84 -0
  93. package/dist/lib/docker.js.map +1 -0
  94. package/dist/lib/migrate.d.ts +9 -0
  95. package/dist/lib/migrate.d.ts.map +1 -0
  96. package/dist/lib/migrate.js +97 -0
  97. package/dist/lib/migrate.js.map +1 -0
  98. package/dist/lib/paths.d.ts +9 -0
  99. package/dist/lib/paths.d.ts.map +1 -0
  100. package/dist/lib/paths.js +28 -0
  101. package/dist/lib/paths.js.map +1 -0
  102. package/dist/lib/prompt.d.ts +14 -0
  103. package/dist/lib/prompt.d.ts.map +1 -0
  104. package/dist/lib/prompt.js +87 -0
  105. package/dist/lib/prompt.js.map +1 -0
  106. package/package.json +4 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC;KAC3C,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;CAwBvB,CAAC,CAAC;AAEH,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,52 @@
1
+ export interface ProjectConfig {
2
+ version?: string;
3
+ database?: string;
4
+ nats?: string;
5
+ redis?: string;
6
+ anthropicApiKey?: string;
7
+ projectRoot?: string;
8
+ codifyRoot?: string;
9
+ connectors?: ConnectorEntry[];
10
+ }
11
+ /** A persisted connector configuration in .codify/config.json */
12
+ export interface ConnectorEntry {
13
+ id: string;
14
+ type: "slack" | "github" | "linear" | "notion";
15
+ credentials: Record<string, string | string[]>;
16
+ addedAt: string;
17
+ lastSyncAt?: string;
18
+ }
19
+ /**
20
+ * Load .codify/config.json from cwd and apply values to process.env.
21
+ * Existing env vars take precedence (won't be overwritten).
22
+ */
23
+ export declare function loadProjectConfig(): Promise<ProjectConfig | null>;
24
+ /**
25
+ * Read the raw .codify/config.json content as an object.
26
+ * Returns null if the file doesn't exist or is unreadable.
27
+ */
28
+ export declare function readRawConfig(): Record<string, unknown> | null;
29
+ /**
30
+ * Write the raw config object back to .codify/config.json.
31
+ * Creates the .codify/ directory if it doesn't exist.
32
+ */
33
+ export declare function writeRawConfig(config: Record<string, unknown>): void;
34
+ /**
35
+ * Load persisted connectors from .codify/config.json.
36
+ */
37
+ export declare function loadConnectors(): ConnectorEntry[];
38
+ /**
39
+ * Add a connector entry to .codify/config.json.
40
+ * Generates a unique ID for the connector (e.g., "slack-a1b2c3").
41
+ */
42
+ export declare function addConnector(entry: Omit<ConnectorEntry, "id" | "addedAt">): ConnectorEntry;
43
+ /**
44
+ * Remove a connector entry from .codify/config.json by ID.
45
+ * Returns the removed entry, or null if not found.
46
+ */
47
+ export declare function removeConnector(id: string): ConnectorEntry | null;
48
+ /**
49
+ * Update the lastSyncAt timestamp for a connector.
50
+ */
51
+ export declare function updateConnectorSyncTime(id: string): void;
52
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA2CvE;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS9D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKpE;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,cAAc,EAAE,CAMjD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,SAAS,CAAC,GAAG,cAAc,CAkB1F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAWjE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAUxD"}
@@ -0,0 +1,142 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { randomBytes } from "node:crypto";
4
+ /**
5
+ * Load .codify/config.json from cwd and apply values to process.env.
6
+ * Existing env vars take precedence (won't be overwritten).
7
+ */
8
+ export async function loadProjectConfig() {
9
+ const configPath = resolve(process.cwd(), ".codify/config.json");
10
+ if (!existsSync(configPath))
11
+ return null;
12
+ try {
13
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
14
+ if (config.codifyRoot && !process.env.CODIFY_ROOT) {
15
+ process.env.CODIFY_ROOT = config.codifyRoot;
16
+ }
17
+ if (config.database && !process.env.DATABASE_URL) {
18
+ process.env.DATABASE_URL = config.database;
19
+ }
20
+ if (config.nats && !process.env.NATS_URL) {
21
+ process.env.NATS_URL = config.nats;
22
+ }
23
+ if (config.redis && !process.env.REDIS_URL) {
24
+ process.env.REDIS_URL = config.redis;
25
+ }
26
+ if (config.anthropicApiKey && !process.env.ANTHROPIC_API_KEY) {
27
+ process.env.ANTHROPIC_API_KEY = config.anthropicApiKey;
28
+ // Throttle deprecation warning to once per 24 hours
29
+ const warnFile = resolve(process.cwd(), ".codify/.deprecation-warned");
30
+ let showWarning = true;
31
+ try {
32
+ if (existsSync(warnFile)) {
33
+ const lastWarn = parseInt(readFileSync(warnFile, "utf-8").trim(), 10);
34
+ if (Date.now() - lastWarn < 24 * 60 * 60 * 1000)
35
+ showWarning = false;
36
+ }
37
+ }
38
+ catch { /* ignore */ }
39
+ if (showWarning) {
40
+ console.warn(" WARN: ANTHROPIC_API_KEY found in .codify/config.json. This is deprecated.");
41
+ console.warn(" Set it as an environment variable instead and remove it from config.");
42
+ try {
43
+ writeFileSync(warnFile, String(Date.now()), "utf-8");
44
+ }
45
+ catch { /* ignore */ }
46
+ }
47
+ }
48
+ return config;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Read the raw .codify/config.json content as an object.
56
+ * Returns null if the file doesn't exist or is unreadable.
57
+ */
58
+ export function readRawConfig() {
59
+ const configPath = resolve(process.cwd(), ".codify/config.json");
60
+ if (!existsSync(configPath))
61
+ return null;
62
+ try {
63
+ return JSON.parse(readFileSync(configPath, "utf-8"));
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ /**
70
+ * Write the raw config object back to .codify/config.json.
71
+ * Creates the .codify/ directory if it doesn't exist.
72
+ */
73
+ export function writeRawConfig(config) {
74
+ const configDir = resolve(process.cwd(), ".codify");
75
+ mkdirSync(configDir, { recursive: true });
76
+ const configPath = resolve(configDir, "config.json");
77
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
78
+ }
79
+ /**
80
+ * Load persisted connectors from .codify/config.json.
81
+ */
82
+ export function loadConnectors() {
83
+ const config = readRawConfig();
84
+ if (!config)
85
+ return [];
86
+ const connectors = config.connectors;
87
+ if (!Array.isArray(connectors))
88
+ return [];
89
+ return connectors;
90
+ }
91
+ /**
92
+ * Add a connector entry to .codify/config.json.
93
+ * Generates a unique ID for the connector (e.g., "slack-a1b2c3").
94
+ */
95
+ export function addConnector(entry) {
96
+ const config = readRawConfig() ?? {};
97
+ if (!Array.isArray(config.connectors)) {
98
+ config.connectors = [];
99
+ }
100
+ const connectors = config.connectors;
101
+ const suffix = randomBytes(3).toString("hex");
102
+ const newEntry = {
103
+ id: `${entry.type}-${suffix}`,
104
+ type: entry.type,
105
+ credentials: entry.credentials,
106
+ addedAt: new Date().toISOString(),
107
+ };
108
+ connectors.push(newEntry);
109
+ writeRawConfig(config);
110
+ return newEntry;
111
+ }
112
+ /**
113
+ * Remove a connector entry from .codify/config.json by ID.
114
+ * Returns the removed entry, or null if not found.
115
+ */
116
+ export function removeConnector(id) {
117
+ const config = readRawConfig();
118
+ if (!config || !Array.isArray(config.connectors))
119
+ return null;
120
+ const connectors = config.connectors;
121
+ const index = connectors.findIndex((c) => c.id === id);
122
+ if (index === -1)
123
+ return null;
124
+ const [removed] = connectors.splice(index, 1);
125
+ writeRawConfig(config);
126
+ return removed;
127
+ }
128
+ /**
129
+ * Update the lastSyncAt timestamp for a connector.
130
+ */
131
+ export function updateConnectorSyncTime(id) {
132
+ const config = readRawConfig();
133
+ if (!config || !Array.isArray(config.connectors))
134
+ return;
135
+ const connectors = config.connectors;
136
+ const entry = connectors.find((c) => c.id === id);
137
+ if (!entry)
138
+ return;
139
+ entry.lastSyncAt = new Date().toISOString();
140
+ writeRawConfig(config);
141
+ }
142
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Check if Docker CLI is installed.
3
+ */
4
+ export declare function isDockerInstalled(): boolean;
5
+ /**
6
+ * Check if Docker daemon is running.
7
+ */
8
+ export declare function isDockerRunning(): boolean;
9
+ /**
10
+ * Copy Docker assets from the npm package to the target directory.
11
+ * Typically copies to `.codify/docker/`.
12
+ */
13
+ export declare function setupDockerAssets(targetDir: string): void;
14
+ /**
15
+ * Start Docker services using compose from the given directory.
16
+ * Streams output so the user sees Docker pull/build progress.
17
+ */
18
+ export declare function startDockerServices(composeDir: string): Promise<void>;
19
+ /**
20
+ * Wait for PostgreSQL to be ready via docker compose exec pg_isready.
21
+ */
22
+ export declare function waitForPostgres(composeDir: string, timeoutMs?: number): Promise<boolean>;
23
+ //# sourceMappingURL=docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/lib/docker.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,SAAS,SAAU,GAClB,OAAO,CAAC,OAAO,CAAC,CAelB"}
@@ -0,0 +1,84 @@
1
+ import { spawnSync, spawn } from "node:child_process";
2
+ import { existsSync, mkdirSync, cpSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { getDockerAssetsDir } from "./paths.js";
5
+ /**
6
+ * Check if Docker CLI is installed.
7
+ */
8
+ export function isDockerInstalled() {
9
+ const result = spawnSync("docker", ["--version"], { stdio: "pipe" });
10
+ return result.status === 0;
11
+ }
12
+ /**
13
+ * Check if Docker daemon is running.
14
+ */
15
+ export function isDockerRunning() {
16
+ const result = spawnSync("docker", ["info"], { stdio: "pipe" });
17
+ return result.status === 0;
18
+ }
19
+ /**
20
+ * Copy Docker assets from the npm package to the target directory.
21
+ * Typically copies to `.codify/docker/`.
22
+ */
23
+ export function setupDockerAssets(targetDir) {
24
+ const sourceDir = getDockerAssetsDir();
25
+ if (!existsSync(sourceDir)) {
26
+ throw new Error(`Docker assets not found at ${sourceDir}`);
27
+ }
28
+ mkdirSync(targetDir, { recursive: true });
29
+ cpSync(sourceDir, targetDir, { recursive: true });
30
+ }
31
+ /**
32
+ * Start Docker services using compose from the given directory.
33
+ * Streams output so the user sees Docker pull/build progress.
34
+ */
35
+ export async function startDockerServices(composeDir) {
36
+ const composePath = resolve(composeDir, "docker-compose.yml");
37
+ if (!existsSync(composePath)) {
38
+ throw new Error(`docker-compose.yml not found at ${composePath}`);
39
+ }
40
+ return new Promise((resolveP, reject) => {
41
+ const child = spawn("docker", ["compose", "-f", composePath, "up", "-d", "--build"], { stdio: ["ignore", "pipe", "pipe"] });
42
+ // Stream Docker output with indentation to match CLI style
43
+ const prefix = " ";
44
+ let lastLine = "";
45
+ const handleData = (data) => {
46
+ const lines = data.toString().split("\n").filter((l) => l.trim());
47
+ for (const line of lines) {
48
+ // Skip duplicate lines (Docker repeats status)
49
+ if (line === lastLine)
50
+ continue;
51
+ lastLine = line;
52
+ console.log(`${prefix}${line}`);
53
+ }
54
+ };
55
+ child.stdout?.on("data", handleData);
56
+ child.stderr?.on("data", handleData);
57
+ child.on("error", (err) => {
58
+ reject(new Error(`Failed to start Docker: ${err.message}`));
59
+ });
60
+ child.on("close", (code) => {
61
+ if (code === 0) {
62
+ resolveP();
63
+ }
64
+ else {
65
+ reject(new Error(`docker compose exited with code ${code}`));
66
+ }
67
+ });
68
+ });
69
+ }
70
+ /**
71
+ * Wait for PostgreSQL to be ready via docker compose exec pg_isready.
72
+ */
73
+ export async function waitForPostgres(composeDir, timeoutMs = 120_000) {
74
+ const composePath = resolve(composeDir, "docker-compose.yml");
75
+ const deadline = Date.now() + timeoutMs;
76
+ while (Date.now() < deadline) {
77
+ const check = spawnSync("docker", ["compose", "-f", composePath, "exec", "-T", "postgres", "pg_isready", "-U", "codify"], { stdio: "pipe" });
78
+ if (check.status === 0)
79
+ return true;
80
+ await new Promise((r) => setTimeout(r, 1000));
81
+ }
82
+ return false;
83
+ }
84
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/lib/docker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAkB;IAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mCAAmC,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,IAAI,OAAO,CAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,KAAK,CACjB,QAAQ,EACR,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,EACrD,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CACtC,CAAC;QAEF,2DAA2D;QAC3D,MAAM,MAAM,GAAG,MAAM,CAAC;QACtB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAElB,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,+CAA+C;gBAC/C,IAAI,IAAI,KAAK,QAAQ;oBAAE,SAAS;gBAChC,QAAQ,GAAG,IAAI,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACrC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAErC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,QAAQ,EAAE,CAAC;YACb,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,SAAS,GAAG,OAAO;IAEnB,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,SAAS,CACrB,QAAQ,EACR,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,EACtF,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;QACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface MigrationResult {
2
+ applied: string[];
3
+ skipped: string[];
4
+ }
5
+ /**
6
+ * Run all pending migrations from the given directory against the database.
7
+ */
8
+ export declare function runMigrations(databaseUrl: string, migrationsDir: string): Promise<MigrationResult>;
9
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/lib/migrate.ts"],"names":[],"mappings":"AAmDA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,eAAe,CAAC,CA0D1B"}
@@ -0,0 +1,97 @@
1
+ import { readFileSync, readdirSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import pg from "pg";
4
+ /**
5
+ * Split SQL into individual statements, respecting $$ blocks.
6
+ */
7
+ function splitStatements(sql) {
8
+ const statements = [];
9
+ let current = "";
10
+ let inDollarBlock = false;
11
+ let i = 0;
12
+ while (i < sql.length) {
13
+ if (sql[i] === "$" && sql[i + 1] === "$") {
14
+ current += "$$";
15
+ inDollarBlock = !inDollarBlock;
16
+ i += 2;
17
+ continue;
18
+ }
19
+ if (sql[i] === ";" && !inDollarBlock) {
20
+ current += ";";
21
+ const trimmed = current.trim();
22
+ if (trimmed && trimmed !== ";") {
23
+ statements.push(trimmed);
24
+ }
25
+ current = "";
26
+ i++;
27
+ continue;
28
+ }
29
+ if (sql[i] === "-" && sql[i + 1] === "-" && !inDollarBlock) {
30
+ const eol = sql.indexOf("\n", i);
31
+ if (eol === -1)
32
+ break;
33
+ i = eol + 1;
34
+ continue;
35
+ }
36
+ current += sql[i];
37
+ i++;
38
+ }
39
+ const trimmed = current.trim();
40
+ if (trimmed && trimmed !== ";") {
41
+ statements.push(trimmed.endsWith(";") ? trimmed : trimmed + ";");
42
+ }
43
+ return statements;
44
+ }
45
+ /**
46
+ * Run all pending migrations from the given directory against the database.
47
+ */
48
+ export async function runMigrations(databaseUrl, migrationsDir) {
49
+ const client = new pg.Client({ connectionString: databaseUrl });
50
+ await client.connect();
51
+ const result = { applied: [], skipped: [] };
52
+ try {
53
+ // Ensure migrations tracking table exists
54
+ await client.query(`
55
+ CREATE TABLE IF NOT EXISTS _migrations (
56
+ name TEXT PRIMARY KEY,
57
+ applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
58
+ )
59
+ `);
60
+ const { rows: applied } = await client.query("SELECT name FROM _migrations ORDER BY name");
61
+ const appliedSet = new Set(applied.map((r) => r.name));
62
+ // Find all migration files, sorted by name
63
+ const migrationFiles = readdirSync(migrationsDir)
64
+ .filter((f) => f.endsWith(".sql"))
65
+ .sort();
66
+ for (const migrationFile of migrationFiles) {
67
+ if (appliedSet.has(migrationFile)) {
68
+ result.skipped.push(migrationFile);
69
+ continue;
70
+ }
71
+ const sql = readFileSync(resolve(migrationsDir, migrationFile), "utf-8");
72
+ const statements = splitStatements(sql);
73
+ for (const stmt of statements) {
74
+ const trimmedUpper = stmt.trim().toUpperCase();
75
+ // Skip LOAD — extensions loaded by Docker init
76
+ if (trimmedUpper.startsWith("LOAD "))
77
+ continue;
78
+ try {
79
+ await client.query(stmt);
80
+ }
81
+ catch (err) {
82
+ const msg = err instanceof Error ? err.message : String(err);
83
+ if (!msg.includes("already exists") && !msg.includes("duplicate key")) {
84
+ throw err;
85
+ }
86
+ }
87
+ }
88
+ await client.query("INSERT INTO _migrations (name) VALUES ($1)", [migrationFile]);
89
+ result.applied.push(migrationFile);
90
+ }
91
+ return result;
92
+ }
93
+ finally {
94
+ await client.end();
95
+ }
96
+ }
97
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/lib/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resolve the assets directory. Works in both bundled and dev modes.
3
+ * - Bundled: dist/index.js → ../assets/
4
+ * - Dev: src/lib/paths.ts → ../../assets/
5
+ */
6
+ export declare function getAssetsDir(): string;
7
+ export declare function getDockerAssetsDir(): string;
8
+ export declare function getMigrationsDir(): string;
9
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAYrC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
@@ -0,0 +1,28 @@
1
+ import { resolve, dirname } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { existsSync } from "node:fs";
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ /**
7
+ * Resolve the assets directory. Works in both bundled and dev modes.
8
+ * - Bundled: dist/index.js → ../assets/
9
+ * - Dev: src/lib/paths.ts → ../../assets/
10
+ */
11
+ export function getAssetsDir() {
12
+ // Try bundled path first (dist/index.js → ../assets/)
13
+ const bundledPath = resolve(__dirname, "../assets");
14
+ if (existsSync(bundledPath))
15
+ return bundledPath;
16
+ // Dev mode (src/lib/paths.ts → ../../assets/)
17
+ const devPath = resolve(__dirname, "../../assets");
18
+ if (existsSync(devPath))
19
+ return devPath;
20
+ throw new Error("Cannot find assets directory. Is Codify installed correctly?");
21
+ }
22
+ export function getDockerAssetsDir() {
23
+ return resolve(getAssetsDir(), "docker");
24
+ }
25
+ export function getMigrationsDir() {
26
+ return resolve(getAssetsDir(), "migrations");
27
+ }
28
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,sDAAsD;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IAEhD,8CAA8C;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAExC,MAAM,IAAI,KAAK,CACb,8DAA8D,CAC/D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAC,YAAY,EAAE,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Ask a question and return the user's answer.
3
+ */
4
+ export declare function prompt(question: string): Promise<string>;
5
+ /**
6
+ * Ask for a secret (e.g., API key). Hides input by disabling echo.
7
+ */
8
+ export declare function promptSecret(question: string): Promise<string>;
9
+ /**
10
+ * Ask a yes/no confirmation question.
11
+ * @param defaultYes - If true, default answer is Yes when user presses Enter
12
+ */
13
+ export declare function confirm(question: string, defaultYes?: boolean): Promise<boolean>;
14
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/lib/prompt.ts"],"names":[],"mappings":"AASA;;GAEG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C9D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAW7E"}
@@ -0,0 +1,87 @@
1
+ import { createInterface } from "node:readline";
2
+ function createRL() {
3
+ return createInterface({
4
+ input: process.stdin,
5
+ output: process.stderr,
6
+ });
7
+ }
8
+ /**
9
+ * Ask a question and return the user's answer.
10
+ */
11
+ export function prompt(question) {
12
+ return new Promise((resolve) => {
13
+ const rl = createRL();
14
+ rl.question(question, (answer) => {
15
+ rl.close();
16
+ resolve(answer.trim());
17
+ });
18
+ });
19
+ }
20
+ /**
21
+ * Ask for a secret (e.g., API key). Hides input by disabling echo.
22
+ */
23
+ export function promptSecret(question) {
24
+ return new Promise((resolve) => {
25
+ const rl = createRL();
26
+ // Write question to stderr manually
27
+ process.stderr.write(question);
28
+ // Disable echo
29
+ if (process.stdin.isTTY) {
30
+ process.stdin.setRawMode(true);
31
+ }
32
+ let input = "";
33
+ const onData = (char) => {
34
+ const c = char.toString();
35
+ if (c === "\n" || c === "\r") {
36
+ if (process.stdin.isTTY) {
37
+ process.stdin.setRawMode(false);
38
+ }
39
+ process.stdin.removeListener("data", onData);
40
+ process.stderr.write("\n");
41
+ rl.close();
42
+ resolve(input.trim());
43
+ }
44
+ else if (c === "\u007f" || c === "\b") {
45
+ // Backspace
46
+ if (input.length > 0) {
47
+ input = input.slice(0, -1);
48
+ process.stderr.write("\b \b");
49
+ }
50
+ }
51
+ else if (c === "\u0003") {
52
+ // Ctrl+C
53
+ if (process.stdin.isTTY) {
54
+ process.stdin.setRawMode(false);
55
+ }
56
+ process.stderr.write("\n");
57
+ rl.close();
58
+ process.exit(1);
59
+ }
60
+ else {
61
+ input += c;
62
+ process.stderr.write("*");
63
+ }
64
+ };
65
+ process.stdin.on("data", onData);
66
+ process.stdin.resume();
67
+ });
68
+ }
69
+ /**
70
+ * Ask a yes/no confirmation question.
71
+ * @param defaultYes - If true, default answer is Yes when user presses Enter
72
+ */
73
+ export function confirm(question, defaultYes = true) {
74
+ const suffix = defaultYes ? "[Y/n]" : "[y/N]";
75
+ return new Promise((resolve) => {
76
+ const rl = createRL();
77
+ rl.question(`${question} ${suffix} `, (answer) => {
78
+ rl.close();
79
+ const a = answer.trim().toLowerCase();
80
+ if (a === "")
81
+ resolve(defaultYes);
82
+ else
83
+ resolve(a === "y" || a === "yes");
84
+ });
85
+ });
86
+ }
87
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/lib/prompt.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codified/cli",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "description": "Codify — Living Context Graph for AI-Native Teams",
6
6
  "repository": {
@@ -26,7 +26,8 @@
26
26
  "dev": "tsx src/index.ts",
27
27
  "build": "tsx esbuild.config.ts",
28
28
  "typecheck": "tsc --noEmit",
29
- "prepublishOnly": "npm run build"
29
+ "prepublishOnly": "npm run build",
30
+ "test": "vitest run"
30
31
  },
31
32
  "dependencies": {
32
33
  "pg": "^8.20.0",
@@ -44,6 +45,7 @@
44
45
  "@codify/metabolism": "workspace:*",
45
46
  "@codify/app": "workspace:*",
46
47
  "@types/pg": "^8.18.0",
48
+ "vitest": "^3.0.0",
47
49
  "commander": "^13.1.0",
48
50
  "esbuild": "^0.25.0",
49
51
  "tsx": "^4.19.0"