steroids-cli 0.14.2 → 0.15.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/dist/commands/ai-run.d.ts +10 -0
- package/dist/commands/ai-run.d.ts.map +1 -0
- package/dist/commands/ai-run.js +255 -0
- package/dist/commands/ai-run.js.map +1 -0
- package/dist/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +7 -1
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/coder-noop-submission.d.ts +2 -2
- package/dist/commands/coder-noop-submission.d.ts.map +1 -1
- package/dist/commands/coder-noop-submission.js +8 -1
- package/dist/commands/coder-noop-submission.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +9 -0
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/loop-phases-coder-decision.d.ts +2 -0
- package/dist/commands/loop-phases-coder-decision.d.ts.map +1 -1
- package/dist/commands/loop-phases-coder-decision.js +18 -41
- package/dist/commands/loop-phases-coder-decision.js.map +1 -1
- package/dist/commands/loop-phases-coder.d.ts.map +1 -1
- package/dist/commands/loop-phases-coder.js +2 -1
- package/dist/commands/loop-phases-coder.js.map +1 -1
- package/dist/commands/loop-phases-reviewer.d.ts.map +1 -1
- package/dist/commands/loop-phases-reviewer.js +78 -74
- package/dist/commands/loop-phases-reviewer.js.map +1 -1
- package/dist/commands/loop.d.ts.map +1 -1
- package/dist/commands/loop.js +6 -0
- package/dist/commands/loop.js.map +1 -1
- package/dist/commands/push-task-branch.d.ts +12 -0
- package/dist/commands/push-task-branch.d.ts.map +1 -0
- package/dist/commands/push-task-branch.js +24 -0
- package/dist/commands/push-task-branch.js.map +1 -0
- package/dist/commands/tasks.js +1 -1
- package/dist/commands/tasks.js.map +1 -1
- package/dist/database/queries.d.ts +8 -2
- package/dist/database/queries.d.ts.map +1 -1
- package/dist/database/queries.js +17 -1
- package/dist/database/queries.js.map +1 -1
- package/dist/git/section-pr.js +1 -1
- package/dist/health/stuck-task-detector-types.d.ts +3 -3
- package/dist/health/stuck-task-detector-types.d.ts.map +1 -1
- package/dist/health/stuck-task-detector.js +21 -5
- package/dist/health/stuck-task-detector.js.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/monitor/investigator-actions.d.ts.map +1 -1
- package/dist/monitor/investigator-actions.js +44 -39
- package/dist/monitor/investigator-actions.js.map +1 -1
- package/dist/monitor/investigator-agent.d.ts +9 -0
- package/dist/monitor/investigator-agent.d.ts.map +1 -1
- package/dist/monitor/investigator-agent.js +2 -0
- package/dist/monitor/investigator-agent.js.map +1 -1
- package/dist/monitor/investigator-helpers.d.ts +5 -0
- package/dist/monitor/investigator-helpers.d.ts.map +1 -0
- package/dist/monitor/investigator-helpers.js +44 -0
- package/dist/monitor/investigator-helpers.js.map +1 -0
- package/dist/monitor/investigator-prompt.d.ts.map +1 -1
- package/dist/monitor/investigator-prompt.js +11 -3
- package/dist/monitor/investigator-prompt.js.map +1 -1
- package/dist/monitor/scanner-queries.d.ts +3 -0
- package/dist/monitor/scanner-queries.d.ts.map +1 -1
- package/dist/monitor/scanner-queries.js +57 -0
- package/dist/monitor/scanner-queries.js.map +1 -1
- package/dist/monitor/scanner.d.ts +1 -1
- package/dist/monitor/scanner.d.ts.map +1 -1
- package/dist/monitor/scanner.js +10 -2
- package/dist/monitor/scanner.js.map +1 -1
- package/dist/orchestrator/merge-queue-rebase.d.ts +27 -0
- package/dist/orchestrator/merge-queue-rebase.d.ts.map +1 -0
- package/dist/orchestrator/merge-queue-rebase.js +355 -0
- package/dist/orchestrator/merge-queue-rebase.js.map +1 -0
- package/dist/orchestrator/merge-queue.d.ts +40 -0
- package/dist/orchestrator/merge-queue.d.ts.map +1 -0
- package/dist/orchestrator/merge-queue.js +352 -0
- package/dist/orchestrator/merge-queue.js.map +1 -0
- package/dist/orchestrator/task-selector.d.ts +2 -1
- package/dist/orchestrator/task-selector.d.ts.map +1 -1
- package/dist/orchestrator/task-selector.js +20 -5
- package/dist/orchestrator/task-selector.js.map +1 -1
- package/dist/parallel/clone.d.ts +0 -15
- package/dist/parallel/clone.d.ts.map +1 -1
- package/dist/parallel/clone.js +0 -37
- package/dist/parallel/clone.js.map +1 -1
- package/dist/providers/invocation-logger.d.ts +2 -2
- package/dist/providers/invocation-logger.d.ts.map +1 -1
- package/dist/providers/invocation-logger.js +1 -1
- package/dist/providers/invocation-logger.js.map +1 -1
- package/dist/runners/daemon.d.ts.map +1 -1
- package/dist/runners/daemon.js +0 -79
- package/dist/runners/daemon.js.map +1 -1
- package/dist/runners/orchestrator-loop.d.ts.map +1 -1
- package/dist/runners/orchestrator-loop.js +11 -29
- package/dist/runners/orchestrator-loop.js.map +1 -1
- package/dist/runners/wakeup-checks.js +1 -1
- package/dist/runners/wakeup-checks.js.map +1 -1
- package/dist/runners/wakeup-sanitise-recovery.d.ts +21 -0
- package/dist/runners/wakeup-sanitise-recovery.d.ts.map +1 -0
- package/dist/runners/wakeup-sanitise-recovery.js +209 -0
- package/dist/runners/wakeup-sanitise-recovery.js.map +1 -0
- package/dist/runners/wakeup-sanitise.d.ts +1 -1
- package/dist/runners/wakeup-sanitise.d.ts.map +1 -1
- package/dist/runners/wakeup-sanitise.js +58 -179
- package/dist/runners/wakeup-sanitise.js.map +1 -1
- package/dist/workspace/git-helpers.d.ts +8 -0
- package/dist/workspace/git-helpers.d.ts.map +1 -1
- package/dist/workspace/git-helpers.js +34 -0
- package/dist/workspace/git-helpers.js.map +1 -1
- package/dist/workspace/merge-lock.d.ts +5 -3
- package/dist/workspace/merge-lock.d.ts.map +1 -1
- package/dist/workspace/merge-lock.js +16 -15
- package/dist/workspace/merge-lock.js.map +1 -1
- package/migrations/028_add_merge_queue_fields.sql +8 -0
- package/migrations/manifest.json +9 -1
- package/package.json +1 -1
|
@@ -10,12 +10,15 @@ exports.hasMidRebase = hasMidRebase;
|
|
|
10
10
|
exports.abortRebase = abortRebase;
|
|
11
11
|
exports.resolveBaseBranch = resolveBaseBranch;
|
|
12
12
|
exports.pushWithRetries = pushWithRetries;
|
|
13
|
+
exports.pushWithRetriesAsync = pushWithRetriesAsync;
|
|
13
14
|
exports.isAncestor = isAncestor;
|
|
14
15
|
exports.getStatusPorcelain = getStatusPorcelain;
|
|
15
16
|
exports.getLogOneline = getLogOneline;
|
|
16
17
|
const node_child_process_1 = require("node:child_process");
|
|
17
18
|
const node_fs_1 = require("node:fs");
|
|
18
19
|
const node_path_1 = require("node:path");
|
|
20
|
+
const node_util_1 = require("node:util");
|
|
21
|
+
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
19
22
|
/**
|
|
20
23
|
* Run a git command synchronously. Returns trimmed stdout on success.
|
|
21
24
|
* Throws on non-zero exit unless `tolerateFailure` is set.
|
|
@@ -109,6 +112,37 @@ function pushWithRetries(cwd, remote, refspec, retries = 3, backoffMs = [1000, 4
|
|
|
109
112
|
}
|
|
110
113
|
return { success: false, error: `Push failed after ${retries} attempts: ${lastError}` };
|
|
111
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Async version of pushWithRetries — uses setTimeout instead of busy-wait
|
|
117
|
+
* so heartbeat timers can fire during backoff delays.
|
|
118
|
+
*/
|
|
119
|
+
async function pushWithRetriesAsync(cwd, remote, refspec, retries = 3, backoffMs = [1000, 4000, 16000], forceWithLease = false) {
|
|
120
|
+
const pushArgs = ['push', remote, refspec];
|
|
121
|
+
if (forceWithLease) {
|
|
122
|
+
pushArgs.push('--force-with-lease');
|
|
123
|
+
}
|
|
124
|
+
let lastError = '';
|
|
125
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
126
|
+
try {
|
|
127
|
+
await execFileAsync('git', pushArgs, {
|
|
128
|
+
cwd,
|
|
129
|
+
encoding: 'utf-8',
|
|
130
|
+
timeout: 120_000,
|
|
131
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
|
|
132
|
+
});
|
|
133
|
+
return { success: true };
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
137
|
+
const stderr = err?.stderr ?? '';
|
|
138
|
+
lastError = stderr.trim() || msg;
|
|
139
|
+
}
|
|
140
|
+
if (attempt < retries - 1 && attempt < backoffMs.length) {
|
|
141
|
+
await new Promise(r => setTimeout(r, backoffMs[attempt]));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { success: false, error: `Push failed after ${retries} attempts: ${lastError}` };
|
|
145
|
+
}
|
|
112
146
|
/**
|
|
113
147
|
* Check if `ancestor` is an ancestor of `descendant`.
|
|
114
148
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-helpers.js","sourceRoot":"","sources":["../../src/workspace/git-helpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;
|
|
1
|
+
{"version":3,"file":"git-helpers.js","sourceRoot":"","sources":["../../src/workspace/git-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
import type Database from 'better-sqlite3';
|
|
8
8
|
/**
|
|
9
9
|
* Attempt to acquire the merge lock for a project.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* When `tryOnce` is true, makes a single attempt and returns immediately.
|
|
12
|
+
* Otherwise polls every `pollMs` until `timeoutMs` elapses.
|
|
13
|
+
* Reclaims stale locks older than 90 seconds.
|
|
12
14
|
*
|
|
13
15
|
* Returns true if the lock was acquired.
|
|
14
16
|
*/
|
|
15
|
-
export declare function acquireWorkspaceMergeLock(globalDb: Database.Database, projectId: string, runnerId: string, slotId: number, timeoutMs?: number, pollMs?: number): boolean;
|
|
17
|
+
export declare function acquireWorkspaceMergeLock(globalDb: Database.Database, projectId: string, runnerId: string, slotId: number, timeoutMs?: number, pollMs?: number, tryOnce?: boolean): boolean;
|
|
16
18
|
/**
|
|
17
19
|
* Release the merge lock for a project.
|
|
18
20
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-lock.d.ts","sourceRoot":"","sources":["../../src/workspace/merge-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"merge-lock.d.ts","sourceRoot":"","sources":["../../src/workspace/merge-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAgB,EAC3B,MAAM,GAAE,MAAc,EACtB,OAAO,GAAE,OAAe,GACvB,OAAO,CA8DT;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAC3B,SAAS,EAAE,MAAM,GAChB,IAAI,CAIN;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,IAAI,CAQN"}
|
|
@@ -9,37 +9,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.acquireWorkspaceMergeLock = acquireWorkspaceMergeLock;
|
|
10
10
|
exports.releaseWorkspaceMergeLock = releaseWorkspaceMergeLock;
|
|
11
11
|
exports.refreshWorkspaceMergeLockHeartbeat = refreshWorkspaceMergeLockHeartbeat;
|
|
12
|
+
const STALE_LOCK_TTL_MS = 90_000; // 90s — merge queue uses heartbeats, so stale = missed ~3 heartbeat cycles
|
|
12
13
|
/**
|
|
13
14
|
* Attempt to acquire the merge lock for a project.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
*
|
|
16
|
+
* When `tryOnce` is true, makes a single attempt and returns immediately.
|
|
17
|
+
* Otherwise polls every `pollMs` until `timeoutMs` elapses.
|
|
18
|
+
* Reclaims stale locks older than 90 seconds.
|
|
16
19
|
*
|
|
17
20
|
* Returns true if the lock was acquired.
|
|
18
21
|
*/
|
|
19
|
-
function acquireWorkspaceMergeLock(globalDb, projectId, runnerId, slotId, timeoutMs = 300_000, pollMs = 5_000) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
while (Date.now() < deadline) {
|
|
23
|
-
const acquired = globalDb.transaction(() => {
|
|
24
|
-
// Check for existing lock
|
|
22
|
+
function acquireWorkspaceMergeLock(globalDb, projectId, runnerId, slotId, timeoutMs = 300_000, pollMs = 5_000, tryOnce = false) {
|
|
23
|
+
const attemptAcquire = () => {
|
|
24
|
+
return globalDb.transaction(() => {
|
|
25
25
|
const existing = globalDb
|
|
26
26
|
.prepare('SELECT * FROM workspace_merge_locks WHERE project_id = ?')
|
|
27
27
|
.get(projectId);
|
|
28
28
|
if (existing) {
|
|
29
|
-
// Check if stale
|
|
30
29
|
const age = Date.now() - existing.heartbeat_at;
|
|
31
30
|
if (age > STALE_LOCK_TTL_MS) {
|
|
32
|
-
// Reclaim stale lock
|
|
33
31
|
globalDb
|
|
34
32
|
.prepare('DELETE FROM workspace_merge_locks WHERE id = ?')
|
|
35
33
|
.run(existing.id);
|
|
36
34
|
}
|
|
37
35
|
else {
|
|
38
|
-
// Lock is held by another runner
|
|
39
36
|
return false;
|
|
40
37
|
}
|
|
41
38
|
}
|
|
42
|
-
// Insert new lock
|
|
43
39
|
const now = Date.now();
|
|
44
40
|
try {
|
|
45
41
|
globalDb
|
|
@@ -51,15 +47,20 @@ function acquireWorkspaceMergeLock(globalDb, projectId, runnerId, slotId, timeou
|
|
|
51
47
|
}
|
|
52
48
|
catch (error) {
|
|
53
49
|
if (error.message?.includes('UNIQUE constraint')) {
|
|
54
|
-
return false;
|
|
50
|
+
return false;
|
|
55
51
|
}
|
|
56
52
|
throw error;
|
|
57
53
|
}
|
|
58
54
|
}).immediate();
|
|
59
|
-
|
|
55
|
+
};
|
|
56
|
+
if (tryOnce) {
|
|
57
|
+
return attemptAcquire();
|
|
58
|
+
}
|
|
59
|
+
const deadline = Date.now() + timeoutMs;
|
|
60
|
+
while (Date.now() < deadline) {
|
|
61
|
+
if (attemptAcquire()) {
|
|
60
62
|
return true;
|
|
61
63
|
}
|
|
62
|
-
// Wait before retrying
|
|
63
64
|
const remaining = deadline - Date.now();
|
|
64
65
|
if (remaining <= 0)
|
|
65
66
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-lock.js","sourceRoot":"","sources":["../../src/workspace/merge-lock.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;
|
|
1
|
+
{"version":3,"file":"merge-lock.js","sourceRoot":"","sources":["../../src/workspace/merge-lock.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAeH,8DAsEC;AAKD,8DAOC;AAMD,gFAYC;AA/GD,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,2EAA2E;AAE7G;;;;;;;;GAQG;AACH,SAAgB,yBAAyB,CACvC,QAA2B,EAC3B,SAAiB,EACjB,QAAgB,EAChB,MAAc,EACd,YAAoB,OAAO,EAC3B,SAAiB,KAAK,EACtB,UAAmB,KAAK;IAExB,MAAM,cAAc,GAAG,GAAY,EAAE;QACnC,OAAO,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE;YAC/B,MAAM,QAAQ,GAAG,QAAQ;iBACtB,OAAO,CAAC,0DAA0D,CAAC;iBACnE,GAAG,CAAC,SAAS,CAIH,CAAC;YAEd,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAC/C,IAAI,GAAG,GAAG,iBAAiB,EAAE,CAAC;oBAC5B,QAAQ;yBACL,OAAO,CAAC,gDAAgD,CAAC;yBACzD,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,QAAQ;qBACL,OAAO,CACN;;oCAEwB,CACzB;qBACA,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC9C,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBACjD,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,cAAc,EAAE,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxC,IAAI,SAAS,IAAI,CAAC;YAAE,MAAM;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAC/B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;YACxB,gDAAgD;QAClD,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,yBAAyB,CACvC,QAA2B,EAC3B,SAAiB;IAEjB,QAAQ;SACL,OAAO,CAAC,wDAAwD,CAAC;SACjE,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,SAAgB,kCAAkC,CAChD,QAA2B,EAC3B,SAAiB,EACjB,QAAgB;IAEhB,QAAQ;SACL,OAAO,CACN;;8CAEwC,CACzC;SACA,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- UP
|
|
2
|
+
ALTER TABLE tasks ADD COLUMN merge_phase TEXT;
|
|
3
|
+
ALTER TABLE tasks ADD COLUMN approved_sha TEXT;
|
|
4
|
+
ALTER TABLE tasks ADD COLUMN rebase_attempts INTEGER DEFAULT 0;
|
|
5
|
+
|
|
6
|
+
-- DOWN
|
|
7
|
+
-- SQLite does not support DROP COLUMN; these columns are nullable/defaulted
|
|
8
|
+
-- and harmless if left in place after rollback.
|
package/migrations/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.2.3",
|
|
3
|
-
"latestDbVersion":
|
|
3
|
+
"latestDbVersion": 28,
|
|
4
4
|
"migrations": [
|
|
5
5
|
{
|
|
6
6
|
"id": 1,
|
|
@@ -217,6 +217,14 @@
|
|
|
217
217
|
"description": "Add task_dependencies table for explicit task-level dependency tracking",
|
|
218
218
|
"checksum": "",
|
|
219
219
|
"cliVersion": "0.12.7"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"id": 28,
|
|
223
|
+
"name": "028_add_merge_queue_fields",
|
|
224
|
+
"file": "028_add_merge_queue_fields.sql",
|
|
225
|
+
"description": "Add merge_phase, approved_sha, rebase_attempts columns for merge queue pipeline",
|
|
226
|
+
"checksum": "",
|
|
227
|
+
"cliVersion": "0.14.3"
|
|
220
228
|
}
|
|
221
229
|
]
|
|
222
230
|
}
|