@deksden-com/dd-flow-cli 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/README.md +274 -0
- package/dist/cli/help.js +308 -0
- package/dist/cli/run-cli.js +945 -0
- package/dist/cli.js +4 -0
- package/dist/domain/contracts.js +57 -0
- package/dist/domain/entity-ids.js +47 -0
- package/dist/domain/flow-contract.js +233 -0
- package/dist/domain/validation.js +91 -0
- package/dist/protocol/local-files.js +141 -0
- package/dist/runtime/context.js +11 -0
- package/dist/schemas/code-stage-report.schema.json +181 -0
- package/dist/schemas/flow-run-index.schema.json +129 -0
- package/dist/schemas/mb-upgrade-review-data.schema.json +813 -0
- package/dist/schemas/memorybank-permissions-preflight.schema.json +154 -0
- package/dist/schemas/merge-stage-report.schema.json +135 -0
- package/dist/services/audit.js +19 -0
- package/dist/services/cleanup.js +310 -0
- package/dist/services/config.js +143 -0
- package/dist/services/dashboard.js +436 -0
- package/dist/services/hooks.js +929 -0
- package/dist/services/lanes.js +327 -0
- package/dist/services/memory-permissions.js +344 -0
- package/dist/services/merge-queue.js +333 -0
- package/dist/services/plans.js +149 -0
- package/dist/services/projects.js +286 -0
- package/dist/services/protocols.js +606 -0
- package/dist/services/runs.js +359 -0
- package/dist/services/schema-validation.js +185 -0
- package/dist/services/sessions.js +365 -0
- package/dist/services/worktrees.js +204 -0
- package/dist/shared/errors.js +14 -0
- package/dist/shared/json.js +17 -0
- package/dist/storage/database.js +325 -0
- package/dist/storage/paths.js +56 -0
- package/package.json +44 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { ensureDir } from "./paths.js";
|
|
5
|
+
import { AppError } from "../shared/errors.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const { DatabaseSync } = require("node:sqlite");
|
|
8
|
+
export function getDatabase(ddFlowHome) {
|
|
9
|
+
ensureDir(ddFlowHome);
|
|
10
|
+
const dbPath = path.join(ddFlowHome, "db.sqlite");
|
|
11
|
+
const db = new DatabaseSync(dbPath);
|
|
12
|
+
configureDatabase(db);
|
|
13
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
14
|
+
migrate(db);
|
|
15
|
+
return {
|
|
16
|
+
path: dbPath,
|
|
17
|
+
exec: (sql) => db.exec(sql),
|
|
18
|
+
run: (sql, params = []) => db.prepare(sql).run(...params),
|
|
19
|
+
get: (sql, params = []) => db.prepare(sql).get(...params),
|
|
20
|
+
all: (sql, params = []) => db.prepare(sql).all(...params)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function configureDatabase(db) {
|
|
24
|
+
db.exec(`
|
|
25
|
+
PRAGMA busy_timeout = 4000;
|
|
26
|
+
PRAGMA journal_mode = WAL;
|
|
27
|
+
PRAGMA synchronous = NORMAL;
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
function migrate(db) {
|
|
31
|
+
db.exec(`
|
|
32
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
short_id TEXT,
|
|
35
|
+
slug TEXT,
|
|
36
|
+
root TEXT NOT NULL UNIQUE,
|
|
37
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
38
|
+
state_root TEXT,
|
|
39
|
+
created_at TEXT NOT NULL,
|
|
40
|
+
updated_at TEXT NOT NULL
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE TABLE IF NOT EXISTS protocols (
|
|
44
|
+
id TEXT PRIMARY KEY,
|
|
45
|
+
handshake_id TEXT NOT NULL,
|
|
46
|
+
project_id TEXT NOT NULL,
|
|
47
|
+
project_root TEXT NOT NULL,
|
|
48
|
+
status TEXT NOT NULL,
|
|
49
|
+
stage TEXT NOT NULL,
|
|
50
|
+
next_action TEXT,
|
|
51
|
+
route_json TEXT NOT NULL,
|
|
52
|
+
workspace_json TEXT NOT NULL,
|
|
53
|
+
blockers_json TEXT NOT NULL,
|
|
54
|
+
active_def_json TEXT NOT NULL,
|
|
55
|
+
state_path TEXT NOT NULL,
|
|
56
|
+
plan_path TEXT NOT NULL,
|
|
57
|
+
created_at TEXT NOT NULL,
|
|
58
|
+
updated_at TEXT NOT NULL,
|
|
59
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE TABLE IF NOT EXISTS plans (
|
|
63
|
+
protocol_id TEXT PRIMARY KEY,
|
|
64
|
+
plan_json TEXT NOT NULL,
|
|
65
|
+
updated_at TEXT NOT NULL,
|
|
66
|
+
FOREIGN KEY(protocol_id) REFERENCES protocols(id)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
CREATE TABLE IF NOT EXISTS audit_events (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
protocol_id TEXT,
|
|
72
|
+
project_id TEXT,
|
|
73
|
+
event_type TEXT NOT NULL,
|
|
74
|
+
forced INTEGER NOT NULL DEFAULT 0,
|
|
75
|
+
reason TEXT,
|
|
76
|
+
payload_json TEXT NOT NULL,
|
|
77
|
+
created_at TEXT NOT NULL
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
CREATE TABLE IF NOT EXISTS merge_queue (
|
|
81
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
82
|
+
protocol_id TEXT NOT NULL UNIQUE,
|
|
83
|
+
project_id TEXT NOT NULL,
|
|
84
|
+
status TEXT NOT NULL,
|
|
85
|
+
claimed_by_session_id TEXT,
|
|
86
|
+
claimed_at TEXT,
|
|
87
|
+
attempts_count INTEGER NOT NULL DEFAULT 0,
|
|
88
|
+
last_reason TEXT,
|
|
89
|
+
completed_at TEXT,
|
|
90
|
+
created_at TEXT NOT NULL,
|
|
91
|
+
updated_at TEXT NOT NULL
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
CREATE TABLE IF NOT EXISTS merge_sessions (
|
|
95
|
+
session_id TEXT NOT NULL,
|
|
96
|
+
project_id TEXT NOT NULL,
|
|
97
|
+
status TEXT NOT NULL,
|
|
98
|
+
current_protocol_id TEXT,
|
|
99
|
+
stop_reason TEXT,
|
|
100
|
+
started_at TEXT NOT NULL,
|
|
101
|
+
updated_at TEXT NOT NULL,
|
|
102
|
+
stopped_at TEXT,
|
|
103
|
+
PRIMARY KEY (session_id, project_id),
|
|
104
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
CREATE TABLE IF NOT EXISTS lanes (
|
|
108
|
+
project_id TEXT NOT NULL,
|
|
109
|
+
name TEXT NOT NULL,
|
|
110
|
+
workspace_path TEXT NOT NULL,
|
|
111
|
+
expected_branch TEXT,
|
|
112
|
+
status TEXT NOT NULL,
|
|
113
|
+
created_at TEXT NOT NULL,
|
|
114
|
+
updated_at TEXT NOT NULL,
|
|
115
|
+
PRIMARY KEY (project_id, name),
|
|
116
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
CREATE TABLE IF NOT EXISTS lane_locks (
|
|
120
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
121
|
+
project_id TEXT NOT NULL,
|
|
122
|
+
lane TEXT NOT NULL,
|
|
123
|
+
worker_id TEXT NOT NULL,
|
|
124
|
+
status TEXT NOT NULL,
|
|
125
|
+
lease_token TEXT NOT NULL,
|
|
126
|
+
acquired_at TEXT NOT NULL,
|
|
127
|
+
heartbeat_at TEXT NOT NULL,
|
|
128
|
+
expires_at TEXT NOT NULL,
|
|
129
|
+
released_at TEXT,
|
|
130
|
+
reason TEXT,
|
|
131
|
+
metadata_json TEXT NOT NULL,
|
|
132
|
+
created_at TEXT NOT NULL,
|
|
133
|
+
updated_at TEXT NOT NULL,
|
|
134
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_lane_locks_one_active
|
|
138
|
+
ON lane_locks(project_id, lane)
|
|
139
|
+
WHERE status = 'active';
|
|
140
|
+
|
|
141
|
+
CREATE TABLE IF NOT EXISTS hook_installations (
|
|
142
|
+
project_id TEXT NOT NULL,
|
|
143
|
+
scope TEXT NOT NULL,
|
|
144
|
+
config_path TEXT NOT NULL,
|
|
145
|
+
content_hash TEXT NOT NULL,
|
|
146
|
+
installed INTEGER NOT NULL,
|
|
147
|
+
drift_status TEXT NOT NULL,
|
|
148
|
+
created_at TEXT NOT NULL,
|
|
149
|
+
updated_at TEXT NOT NULL,
|
|
150
|
+
PRIMARY KEY (project_id, scope),
|
|
151
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
CREATE TABLE IF NOT EXISTS codex_home_profiles (
|
|
155
|
+
id TEXT PRIMARY KEY,
|
|
156
|
+
project_id TEXT NOT NULL,
|
|
157
|
+
profile TEXT NOT NULL,
|
|
158
|
+
source_home TEXT NOT NULL,
|
|
159
|
+
target_home TEXT NOT NULL,
|
|
160
|
+
config_path TEXT NOT NULL,
|
|
161
|
+
hooks_path TEXT NOT NULL,
|
|
162
|
+
status TEXT NOT NULL,
|
|
163
|
+
created_at TEXT NOT NULL,
|
|
164
|
+
updated_at TEXT NOT NULL,
|
|
165
|
+
last_checked_at TEXT,
|
|
166
|
+
last_drift_status TEXT NOT NULL,
|
|
167
|
+
UNIQUE(project_id, profile),
|
|
168
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
CREATE TABLE IF NOT EXISTS codex_session_bindings (
|
|
172
|
+
session_id TEXT NOT NULL,
|
|
173
|
+
project_id TEXT NOT NULL,
|
|
174
|
+
protocol_id TEXT,
|
|
175
|
+
handshake_id TEXT,
|
|
176
|
+
cwd TEXT,
|
|
177
|
+
transcript_path TEXT,
|
|
178
|
+
status TEXT NOT NULL,
|
|
179
|
+
continuation_count INTEGER NOT NULL DEFAULT 0,
|
|
180
|
+
last_action_hash TEXT,
|
|
181
|
+
created_at TEXT NOT NULL,
|
|
182
|
+
updated_at TEXT NOT NULL,
|
|
183
|
+
PRIMARY KEY(session_id, project_id),
|
|
184
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
CREATE TABLE IF NOT EXISTS project_config (
|
|
188
|
+
project_id TEXT NOT NULL,
|
|
189
|
+
key TEXT NOT NULL,
|
|
190
|
+
value_json TEXT NOT NULL,
|
|
191
|
+
created_at TEXT NOT NULL,
|
|
192
|
+
updated_at TEXT NOT NULL,
|
|
193
|
+
PRIMARY KEY(project_id, key),
|
|
194
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE TABLE IF NOT EXISTS flow_sessions (
|
|
198
|
+
session_id TEXT NOT NULL,
|
|
199
|
+
project_id TEXT NOT NULL,
|
|
200
|
+
project_root TEXT NOT NULL,
|
|
201
|
+
flow_kind TEXT NOT NULL,
|
|
202
|
+
status TEXT NOT NULL,
|
|
203
|
+
run_id TEXT,
|
|
204
|
+
protocol_id TEXT,
|
|
205
|
+
worker_id TEXT,
|
|
206
|
+
workspace_path TEXT NOT NULL,
|
|
207
|
+
continuation_policy TEXT NOT NULL,
|
|
208
|
+
current_stage TEXT,
|
|
209
|
+
next_action TEXT,
|
|
210
|
+
last_action_hash TEXT,
|
|
211
|
+
continuation_count INTEGER NOT NULL DEFAULT 0,
|
|
212
|
+
stop_reason TEXT,
|
|
213
|
+
transcript_path TEXT,
|
|
214
|
+
cwd TEXT,
|
|
215
|
+
metadata_json TEXT NOT NULL,
|
|
216
|
+
created_at TEXT NOT NULL,
|
|
217
|
+
updated_at TEXT NOT NULL,
|
|
218
|
+
stopped_at TEXT,
|
|
219
|
+
PRIMARY KEY(session_id, project_id),
|
|
220
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
CREATE TABLE IF NOT EXISTS flow_runs (
|
|
224
|
+
id TEXT PRIMARY KEY,
|
|
225
|
+
short_id TEXT NOT NULL,
|
|
226
|
+
slug TEXT NOT NULL,
|
|
227
|
+
project_id TEXT NOT NULL,
|
|
228
|
+
project_root TEXT NOT NULL,
|
|
229
|
+
workspace_root TEXT NOT NULL,
|
|
230
|
+
flow_kind TEXT NOT NULL,
|
|
231
|
+
subject_type TEXT NOT NULL,
|
|
232
|
+
subject_id TEXT NOT NULL,
|
|
233
|
+
status TEXT NOT NULL,
|
|
234
|
+
verdict TEXT NOT NULL,
|
|
235
|
+
next_action TEXT,
|
|
236
|
+
runtime_path TEXT NOT NULL,
|
|
237
|
+
run_dir TEXT NOT NULL,
|
|
238
|
+
run_index_path TEXT NOT NULL,
|
|
239
|
+
index_json TEXT NOT NULL,
|
|
240
|
+
created_at TEXT NOT NULL,
|
|
241
|
+
updated_at TEXT NOT NULL,
|
|
242
|
+
completed_at TEXT,
|
|
243
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
CREATE INDEX IF NOT EXISTS idx_flow_runs_project_updated
|
|
247
|
+
ON flow_runs(project_id, updated_at DESC);
|
|
248
|
+
|
|
249
|
+
CREATE INDEX IF NOT EXISTS idx_flow_runs_short_id
|
|
250
|
+
ON flow_runs(short_id);
|
|
251
|
+
|
|
252
|
+
CREATE TABLE IF NOT EXISTS pending_flow_session_bindings (
|
|
253
|
+
session_id TEXT NOT NULL,
|
|
254
|
+
project_id TEXT NOT NULL,
|
|
255
|
+
payload_json TEXT NOT NULL,
|
|
256
|
+
cwd TEXT,
|
|
257
|
+
transcript_path TEXT,
|
|
258
|
+
turn_id TEXT,
|
|
259
|
+
status TEXT NOT NULL,
|
|
260
|
+
created_at TEXT NOT NULL,
|
|
261
|
+
updated_at TEXT NOT NULL,
|
|
262
|
+
PRIMARY KEY(session_id, project_id),
|
|
263
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
CREATE TABLE IF NOT EXISTS codex_hook_events (
|
|
267
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
268
|
+
project_id TEXT NOT NULL,
|
|
269
|
+
protocol_id TEXT,
|
|
270
|
+
session_id TEXT,
|
|
271
|
+
turn_id TEXT,
|
|
272
|
+
event_name TEXT NOT NULL,
|
|
273
|
+
tool_name TEXT,
|
|
274
|
+
status TEXT NOT NULL,
|
|
275
|
+
sanitized_summary TEXT NOT NULL,
|
|
276
|
+
created_at TEXT NOT NULL,
|
|
277
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
CREATE TABLE IF NOT EXISTS worktree_records (
|
|
281
|
+
protocol_id TEXT PRIMARY KEY,
|
|
282
|
+
project_id TEXT NOT NULL,
|
|
283
|
+
integration_branch TEXT,
|
|
284
|
+
feature_branch TEXT NOT NULL,
|
|
285
|
+
base_ref TEXT NOT NULL,
|
|
286
|
+
worktree_path TEXT NOT NULL,
|
|
287
|
+
worktrunk_metadata_json TEXT NOT NULL,
|
|
288
|
+
bootstrap_status TEXT NOT NULL,
|
|
289
|
+
status TEXT NOT NULL,
|
|
290
|
+
last_command_result_json TEXT NOT NULL,
|
|
291
|
+
created_at TEXT NOT NULL,
|
|
292
|
+
updated_at TEXT NOT NULL,
|
|
293
|
+
closed_at TEXT,
|
|
294
|
+
FOREIGN KEY(protocol_id) REFERENCES protocols(id),
|
|
295
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
296
|
+
);
|
|
297
|
+
`);
|
|
298
|
+
ensureColumn(db, "projects", "short_id", "ALTER TABLE projects ADD COLUMN short_id TEXT");
|
|
299
|
+
ensureColumn(db, "projects", "slug", "ALTER TABLE projects ADD COLUMN slug TEXT");
|
|
300
|
+
ensureColumn(db, "projects", "status", "ALTER TABLE projects ADD COLUMN status TEXT NOT NULL DEFAULT 'active'");
|
|
301
|
+
ensureColumn(db, "projects", "state_root", "ALTER TABLE projects ADD COLUMN state_root TEXT");
|
|
302
|
+
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_projects_short_id ON projects(short_id) WHERE short_id IS NOT NULL");
|
|
303
|
+
ensureColumn(db, "merge_queue", "claimed_by_session_id", "ALTER TABLE merge_queue ADD COLUMN claimed_by_session_id TEXT");
|
|
304
|
+
ensureColumn(db, "merge_queue", "claimed_at", "ALTER TABLE merge_queue ADD COLUMN claimed_at TEXT");
|
|
305
|
+
ensureColumn(db, "merge_queue", "attempts_count", "ALTER TABLE merge_queue ADD COLUMN attempts_count INTEGER NOT NULL DEFAULT 0");
|
|
306
|
+
ensureColumn(db, "merge_queue", "last_reason", "ALTER TABLE merge_queue ADD COLUMN last_reason TEXT");
|
|
307
|
+
ensureColumn(db, "merge_queue", "completed_at", "ALTER TABLE merge_queue ADD COLUMN completed_at TEXT");
|
|
308
|
+
ensureColumn(db, "codex_session_bindings", "continuation_count", "ALTER TABLE codex_session_bindings ADD COLUMN continuation_count INTEGER NOT NULL DEFAULT 0");
|
|
309
|
+
ensureColumn(db, "codex_session_bindings", "last_action_hash", "ALTER TABLE codex_session_bindings ADD COLUMN last_action_hash TEXT");
|
|
310
|
+
ensureColumn(db, "flow_sessions", "current_stage", "ALTER TABLE flow_sessions ADD COLUMN current_stage TEXT");
|
|
311
|
+
ensureColumn(db, "flow_sessions", "next_action", "ALTER TABLE flow_sessions ADD COLUMN next_action TEXT");
|
|
312
|
+
ensureColumn(db, "flow_sessions", "metadata_json", "ALTER TABLE flow_sessions ADD COLUMN metadata_json TEXT NOT NULL DEFAULT '{}'");
|
|
313
|
+
ensureColumn(db, "flow_sessions", "run_id", "ALTER TABLE flow_sessions ADD COLUMN run_id TEXT");
|
|
314
|
+
}
|
|
315
|
+
function ensureColumn(db, table, column, sql) {
|
|
316
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
317
|
+
if (!columns.some((entry) => entry.name === column)) {
|
|
318
|
+
db.exec(sql);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
export function ensureReadableFile(file) {
|
|
322
|
+
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
|
|
323
|
+
throw new AppError("not_found", `File does not exist: ${file}`, 1);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { AppError } from "../shared/errors.js";
|
|
5
|
+
export function resolveDdFlowHome(env) {
|
|
6
|
+
return path.resolve(env.DD_FLOW_HOME ?? path.join(os.homedir(), ".dd-flow"));
|
|
7
|
+
}
|
|
8
|
+
export function ensureDir(dir) {
|
|
9
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
export function resolveProjectRoot(root) {
|
|
12
|
+
const absolute = path.resolve(root);
|
|
13
|
+
if (!fs.existsSync(absolute)) {
|
|
14
|
+
throw new AppError("not_found", `Project root does not exist: ${absolute}`, 1);
|
|
15
|
+
}
|
|
16
|
+
return fs.realpathSync(absolute);
|
|
17
|
+
}
|
|
18
|
+
export function protocolDir(projectRoot, protocolId) {
|
|
19
|
+
return path.join(projectRoot, ".memory-bank", "protocol", protocolId);
|
|
20
|
+
}
|
|
21
|
+
export function runtimeProtocolDir(ddFlowHome, projectId, protocolId) {
|
|
22
|
+
return path.join(projectRuntimeRoot(ddFlowHome, projectId), "protocols", protocolId);
|
|
23
|
+
}
|
|
24
|
+
export function runtimeStateJsonPath(ddFlowHome, projectId, protocolId) {
|
|
25
|
+
return path.join(runtimeProtocolDir(ddFlowHome, projectId, protocolId), "state.json");
|
|
26
|
+
}
|
|
27
|
+
export function runtimePlanJsonPath(ddFlowHome, projectId, protocolId) {
|
|
28
|
+
return path.join(runtimeProtocolDir(ddFlowHome, projectId, protocolId), "plan.json");
|
|
29
|
+
}
|
|
30
|
+
export function runtimeRunDir(ddFlowHome, projectId, runId) {
|
|
31
|
+
return path.join(projectRuntimeRoot(ddFlowHome, projectId), "runs", runId);
|
|
32
|
+
}
|
|
33
|
+
export function runtimeRunJsonPath(ddFlowHome, projectId, runId) {
|
|
34
|
+
return path.join(runtimeRunDir(ddFlowHome, projectId, runId), "run.json");
|
|
35
|
+
}
|
|
36
|
+
export function userFacingRunDir(workspaceRoot, runId) {
|
|
37
|
+
return path.join(workspaceRoot, ".tasks", "dd-flow-runs", runId);
|
|
38
|
+
}
|
|
39
|
+
export function userFacingRunIndexPath(workspaceRoot, runId) {
|
|
40
|
+
return path.join(userFacingRunDir(workspaceRoot, runId), "run-index.json");
|
|
41
|
+
}
|
|
42
|
+
export function stateJsonPath(projectRoot, protocolId) {
|
|
43
|
+
return path.join(protocolDir(projectRoot, protocolId), "state.json");
|
|
44
|
+
}
|
|
45
|
+
export function planJsonPath(projectRoot, protocolId) {
|
|
46
|
+
return path.join(protocolDir(projectRoot, protocolId), "plan.json");
|
|
47
|
+
}
|
|
48
|
+
export function projectHome(ddFlowHome, projectId) {
|
|
49
|
+
return path.join(ddFlowHome, "projects", projectId);
|
|
50
|
+
}
|
|
51
|
+
export function projectRuntimeRoot(ddFlowHome, projectId) {
|
|
52
|
+
return path.join(projectHome(ddFlowHome, projectId), "runtime");
|
|
53
|
+
}
|
|
54
|
+
export function projectCheckoutRoot(ddFlowHome, projectId) {
|
|
55
|
+
return path.join(projectHome(ddFlowHome, projectId), "checkouts");
|
|
56
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deksden-com/dd-flow-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mechanical runtime CLI for dd-flow workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dd-flow": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=26.0.0",
|
|
15
|
+
"pnpm": ">=10.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@changesets/cli": "^2.31.0",
|
|
19
|
+
"@eslint/js": "^9.39.1",
|
|
20
|
+
"@types/node": "^24.10.1",
|
|
21
|
+
"eslint": "^9.39.1",
|
|
22
|
+
"typescript": "^5.9.3",
|
|
23
|
+
"typescript-eslint": "^8.47.0",
|
|
24
|
+
"vitest": "^4.0.13"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"ajv": "^8.20.0",
|
|
28
|
+
"smol-toml": "^1.6.1",
|
|
29
|
+
"yaml": "^2.9.0"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.build.json && node scripts/copy-assets.mjs",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"lint": "eslint . --max-warnings=0",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"changeset": "changeset",
|
|
41
|
+
"version-packages": "changeset version",
|
|
42
|
+
"release": "pnpm run build && changeset publish"
|
|
43
|
+
}
|
|
44
|
+
}
|