@inteeka/task-cli 0.1.2 → 0.1.4
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/cli.js +171 -45
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1706,12 +1706,61 @@ function autopilotExitCode(code, status) {
|
|
|
1706
1706
|
|
|
1707
1707
|
// src/scan/llm.ts
|
|
1708
1708
|
import { spawn as spawn2 } from "child_process";
|
|
1709
|
+
import { mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
|
|
1710
|
+
import { homedir as homedir4 } from "os";
|
|
1711
|
+
import { join as join6 } from "path";
|
|
1712
|
+
var FIX_PROMPT_JSON_SCHEMA = {
|
|
1713
|
+
type: "object",
|
|
1714
|
+
required: ["summary", "suspected_files", "proposed_changes", "confidence"],
|
|
1715
|
+
additionalProperties: false,
|
|
1716
|
+
properties: {
|
|
1717
|
+
summary: { type: "string", minLength: 1, maxLength: 2e3 },
|
|
1718
|
+
suspected_files: {
|
|
1719
|
+
type: "array",
|
|
1720
|
+
maxItems: 20,
|
|
1721
|
+
items: { type: "string", minLength: 1, maxLength: 500 }
|
|
1722
|
+
},
|
|
1723
|
+
proposed_changes: {
|
|
1724
|
+
type: "array",
|
|
1725
|
+
maxItems: 20,
|
|
1726
|
+
items: {
|
|
1727
|
+
type: "object",
|
|
1728
|
+
required: ["file", "intent"],
|
|
1729
|
+
additionalProperties: false,
|
|
1730
|
+
properties: {
|
|
1731
|
+
file: { type: "string", minLength: 1, maxLength: 500 },
|
|
1732
|
+
intent: { type: "string", minLength: 1, maxLength: 2e3 },
|
|
1733
|
+
rationale: { type: "string", minLength: 1, maxLength: 2e3 }
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
},
|
|
1737
|
+
investigation: {
|
|
1738
|
+
type: "object",
|
|
1739
|
+
additionalProperties: false,
|
|
1740
|
+
properties: {
|
|
1741
|
+
route_match: { type: "string", maxLength: 500 },
|
|
1742
|
+
auth_findings: { type: "string", maxLength: 1500 },
|
|
1743
|
+
middleware_findings: { type: "string", maxLength: 1500 },
|
|
1744
|
+
redirect_findings: { type: "string", maxLength: 1500 },
|
|
1745
|
+
ui_ux_findings: { type: "string", maxLength: 1500 },
|
|
1746
|
+
browser_findings: { type: "string", maxLength: 1500 },
|
|
1747
|
+
api_findings: { type: "string", maxLength: 1500 },
|
|
1748
|
+
data_findings: { type: "string", maxLength: 1500 }
|
|
1749
|
+
}
|
|
1750
|
+
},
|
|
1751
|
+
risk_notes: { type: "string", maxLength: 2e3 },
|
|
1752
|
+
confidence: { type: "string", enum: ["low", "medium", "high"] }
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1709
1755
|
var LlmGenerationError = class extends Error {
|
|
1710
|
-
constructor(reason, message) {
|
|
1756
|
+
constructor(reason, message, debugLogPath) {
|
|
1711
1757
|
super(message);
|
|
1712
1758
|
this.reason = reason;
|
|
1759
|
+
if (debugLogPath !== void 0) this.debugLogPath = debugLogPath;
|
|
1713
1760
|
}
|
|
1761
|
+
debugLogPath;
|
|
1714
1762
|
};
|
|
1763
|
+
var DEBUG = process.env["TASK_SCAN_DEBUG"] === "1";
|
|
1715
1764
|
async function generateFixPromptJson(args) {
|
|
1716
1765
|
const claude = args.claudePath ?? "claude";
|
|
1717
1766
|
const userPrompt = [
|
|
@@ -1719,19 +1768,20 @@ async function generateFixPromptJson(args) {
|
|
|
1719
1768
|
"",
|
|
1720
1769
|
args.ticketBlock,
|
|
1721
1770
|
"",
|
|
1722
|
-
|
|
1723
|
-
"Do not include explanatory prose, markdown fences, or code commentary \u2014 just the JSON object."
|
|
1771
|
+
"Return JSON only matching the supplied schema. Do not include explanatory prose, markdown fences, or commentary."
|
|
1724
1772
|
].join("\n");
|
|
1725
1773
|
const cliArgs = [
|
|
1726
1774
|
"--print",
|
|
1727
|
-
"--
|
|
1775
|
+
"--output-format",
|
|
1776
|
+
"json",
|
|
1777
|
+
"--tools",
|
|
1728
1778
|
"",
|
|
1729
1779
|
"--system-prompt",
|
|
1730
1780
|
args.systemPrompt,
|
|
1731
1781
|
"--model",
|
|
1732
1782
|
args.modelId,
|
|
1733
|
-
"--
|
|
1734
|
-
|
|
1783
|
+
"--json-schema",
|
|
1784
|
+
JSON.stringify(FIX_PROMPT_JSON_SCHEMA)
|
|
1735
1785
|
];
|
|
1736
1786
|
return new Promise((resolve2, reject) => {
|
|
1737
1787
|
let child;
|
|
@@ -1756,26 +1806,48 @@ async function generateFixPromptJson(args) {
|
|
|
1756
1806
|
child.on("error", (err) => {
|
|
1757
1807
|
reject(new LlmGenerationError("spawn_failed", err.message));
|
|
1758
1808
|
});
|
|
1759
|
-
child.on("close", (code, signal) => {
|
|
1809
|
+
child.on("close", async (code, signal) => {
|
|
1760
1810
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
1761
1811
|
reject(new LlmGenerationError("aborted", "claude was aborted"));
|
|
1762
1812
|
return;
|
|
1763
1813
|
}
|
|
1814
|
+
const authFailure = detectAuthFailure(stdoutBuf);
|
|
1815
|
+
if (authFailure) {
|
|
1816
|
+
const dump = await maybeDumpDebug(args.ticketId, stdoutBuf, stderrBuf);
|
|
1817
|
+
reject(
|
|
1818
|
+
new LlmGenerationError(
|
|
1819
|
+
"non_zero_exit",
|
|
1820
|
+
`Claude is not logged in. Run \`claude /login\` once on this machine, then re-run \`task scan\`.${dump ? ` (raw output: ${dump})` : ""}`,
|
|
1821
|
+
dump ?? void 0
|
|
1822
|
+
)
|
|
1823
|
+
);
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1764
1826
|
if (code !== 0) {
|
|
1827
|
+
const dump = await maybeDumpDebug(args.ticketId, stdoutBuf, stderrBuf);
|
|
1765
1828
|
reject(
|
|
1766
1829
|
new LlmGenerationError(
|
|
1767
1830
|
"non_zero_exit",
|
|
1768
|
-
`claude exited with code ${code}: ${stderrBuf.trim().slice(0,
|
|
1831
|
+
`claude exited with code ${code}${dump ? ` (raw output saved to ${dump})` : ""}: ${stderrBuf.trim().slice(0, 600)}`,
|
|
1832
|
+
dump ?? void 0
|
|
1769
1833
|
)
|
|
1770
1834
|
);
|
|
1771
1835
|
return;
|
|
1772
1836
|
}
|
|
1773
|
-
const
|
|
1837
|
+
const innerText = extractEnvelopeText(stdoutBuf);
|
|
1838
|
+
const parsed = parseStructuredJson(innerText);
|
|
1774
1839
|
if (!parsed) {
|
|
1775
|
-
|
|
1840
|
+
const dump = await maybeDumpDebug(args.ticketId, stdoutBuf, stderrBuf);
|
|
1841
|
+
reject(
|
|
1842
|
+
new LlmGenerationError(
|
|
1843
|
+
"no_json",
|
|
1844
|
+
`No JSON object in claude output${dump ? ` (raw output saved to ${dump})` : ""}`,
|
|
1845
|
+
dump ?? void 0
|
|
1846
|
+
)
|
|
1847
|
+
);
|
|
1776
1848
|
return;
|
|
1777
1849
|
}
|
|
1778
|
-
const tokens =
|
|
1850
|
+
const tokens = readEnvelopeTokens(stdoutBuf, userPrompt, innerText);
|
|
1779
1851
|
resolve2({
|
|
1780
1852
|
structured: parsed,
|
|
1781
1853
|
rawText: stdoutBuf,
|
|
@@ -1787,6 +1859,59 @@ async function generateFixPromptJson(args) {
|
|
|
1787
1859
|
child.stdin?.end();
|
|
1788
1860
|
});
|
|
1789
1861
|
}
|
|
1862
|
+
function detectAuthFailure(raw) {
|
|
1863
|
+
const trimmed = raw.trim();
|
|
1864
|
+
if (!trimmed) return false;
|
|
1865
|
+
try {
|
|
1866
|
+
const env = JSON.parse(trimmed);
|
|
1867
|
+
if (env.is_error === true && typeof env.result === "string") {
|
|
1868
|
+
const msg = env.result.toLowerCase();
|
|
1869
|
+
return msg.includes("not logged in") || msg.includes("please run /login") || msg.includes("please log in");
|
|
1870
|
+
}
|
|
1871
|
+
} catch {
|
|
1872
|
+
}
|
|
1873
|
+
return false;
|
|
1874
|
+
}
|
|
1875
|
+
function extractEnvelopeText(raw) {
|
|
1876
|
+
const trimmed = raw.trim();
|
|
1877
|
+
if (!trimmed) return raw;
|
|
1878
|
+
try {
|
|
1879
|
+
const env = JSON.parse(trimmed);
|
|
1880
|
+
if (typeof env.result === "string") return env.result;
|
|
1881
|
+
} catch {
|
|
1882
|
+
}
|
|
1883
|
+
return raw;
|
|
1884
|
+
}
|
|
1885
|
+
function readEnvelopeTokens(raw, userPrompt, innerText) {
|
|
1886
|
+
try {
|
|
1887
|
+
const env = JSON.parse(raw.trim());
|
|
1888
|
+
const inTok = env.input_tokens ?? env.usage?.input_tokens;
|
|
1889
|
+
const outTok = env.output_tokens ?? env.usage?.output_tokens;
|
|
1890
|
+
if (typeof inTok === "number" && typeof outTok === "number") {
|
|
1891
|
+
return { input: inTok, output: outTok };
|
|
1892
|
+
}
|
|
1893
|
+
} catch {
|
|
1894
|
+
}
|
|
1895
|
+
return {
|
|
1896
|
+
input: Math.max(1, Math.round(userPrompt.length / 4)),
|
|
1897
|
+
output: Math.max(1, Math.round(innerText.length / 4))
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1900
|
+
async function maybeDumpDebug(ticketId, stdout, stderr) {
|
|
1901
|
+
if (!DEBUG && stdout.length === 0 && stderr.length === 0) return null;
|
|
1902
|
+
try {
|
|
1903
|
+
const dir = join6(homedir4(), ".cache", "task", "scan-debug");
|
|
1904
|
+
await mkdir5(dir, { recursive: true });
|
|
1905
|
+
const path = join6(dir, `${ticketId}-${Date.now()}.log`);
|
|
1906
|
+
await writeFile6(
|
|
1907
|
+
path,
|
|
1908
|
+
["## ticket_id", ticketId, "", "## stdout", stdout, "", "## stderr", stderr].join("\n")
|
|
1909
|
+
);
|
|
1910
|
+
return path;
|
|
1911
|
+
} catch {
|
|
1912
|
+
return null;
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1790
1915
|
function parseStructuredJson(raw) {
|
|
1791
1916
|
const trimmed = raw.trim();
|
|
1792
1917
|
if (!trimmed) return null;
|
|
@@ -1840,12 +1965,6 @@ function parseStructuredJson(raw) {
|
|
|
1840
1965
|
}
|
|
1841
1966
|
return null;
|
|
1842
1967
|
}
|
|
1843
|
-
function estimateTokens(input, output) {
|
|
1844
|
-
return {
|
|
1845
|
-
input: Math.max(1, Math.round(input.length / 4)),
|
|
1846
|
-
output: Math.max(1, Math.round(output.length / 4))
|
|
1847
|
-
};
|
|
1848
|
-
}
|
|
1849
1968
|
|
|
1850
1969
|
// src/commands/scan.ts
|
|
1851
1970
|
function registerScan(program2) {
|
|
@@ -1984,11 +2103,12 @@ ${c.bold(`${project.organisation_slug}/${project.project_slug}`)} ${c.dim(`(${pr
|
|
|
1984
2103
|
const spinner = silent ? null : ora2(`#${ticket.sequence_number} ${ticket.title.slice(0, 60)}`).start();
|
|
1985
2104
|
try {
|
|
1986
2105
|
const generated = await safeGenerate(ticket, claudePath);
|
|
1987
|
-
if (!generated) {
|
|
2106
|
+
if (!generated.ok) {
|
|
1988
2107
|
agg.skipped += 1;
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
);
|
|
2108
|
+
const debugSuffix = generated.debugLogPath ? ` \u2014 debug: ${generated.debugLogPath}` : " \u2014 re-run with TASK_SCAN_DEBUG=1 to capture raw output";
|
|
2109
|
+
spinner?.warn(`#${ticket.sequence_number} skipped (${generated.reason})${debugSuffix}`);
|
|
2110
|
+
await api.abort(skillToken, [ticket.ticket_id]).catch(() => void 0);
|
|
2111
|
+
inFlight.delete(ticket.ticket_id);
|
|
1992
2112
|
continue;
|
|
1993
2113
|
}
|
|
1994
2114
|
const result = await api.submit({
|
|
@@ -2047,12 +2167,18 @@ async function safeGenerate(ticket, claudePath) {
|
|
|
2047
2167
|
ticketBlock: ticket.ticket_block,
|
|
2048
2168
|
outputSchemaHint: ticket.output_schema_hint,
|
|
2049
2169
|
modelId: ticket.model_id,
|
|
2170
|
+
ticketId: ticket.ticket_id,
|
|
2050
2171
|
...claudePath ? { claudePath } : {}
|
|
2051
2172
|
});
|
|
2052
|
-
return out;
|
|
2173
|
+
return { ok: true, ...out };
|
|
2053
2174
|
} catch (err) {
|
|
2054
2175
|
if (err instanceof LlmGenerationError) {
|
|
2055
|
-
|
|
2176
|
+
const result = {
|
|
2177
|
+
ok: false,
|
|
2178
|
+
reason: `${err.reason}: ${err.message.slice(0, 200)}`
|
|
2179
|
+
};
|
|
2180
|
+
if (err.debugLogPath) result.debugLogPath = err.debugLogPath;
|
|
2181
|
+
return result;
|
|
2056
2182
|
}
|
|
2057
2183
|
throw err;
|
|
2058
2184
|
}
|
|
@@ -2070,9 +2196,9 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
2070
2196
|
import { platform as platform2 } from "os";
|
|
2071
2197
|
|
|
2072
2198
|
// src/scheduler/launchd.ts
|
|
2073
|
-
import { mkdir as
|
|
2074
|
-
import { homedir as
|
|
2075
|
-
import { join as
|
|
2199
|
+
import { mkdir as mkdir6, readFile as readFile5, writeFile as writeFile7, unlink as unlink3, readdir } from "fs/promises";
|
|
2200
|
+
import { homedir as homedir5 } from "os";
|
|
2201
|
+
import { join as join7 } from "path";
|
|
2076
2202
|
import { execFileSync as execFileSync5, spawn as spawn3 } from "child_process";
|
|
2077
2203
|
|
|
2078
2204
|
// src/scheduler/cron-translate.ts
|
|
@@ -2174,14 +2300,14 @@ function expandField(field, min, max) {
|
|
|
2174
2300
|
}
|
|
2175
2301
|
|
|
2176
2302
|
// src/scheduler/launchd.ts
|
|
2177
|
-
var PLIST_DIR =
|
|
2303
|
+
var PLIST_DIR = join7(homedir5(), "Library", "LaunchAgents");
|
|
2178
2304
|
var LABEL_PREFIX = "com.inteeka.task.cli.";
|
|
2179
2305
|
var SAFE_ID_RE = /^[0-9a-zA-Z._-]+$/;
|
|
2180
2306
|
function plistPath(id) {
|
|
2181
2307
|
if (!SAFE_ID_RE.test(id) || id.includes("..")) {
|
|
2182
2308
|
throw new Error(`Refusing to compute plist path for unsafe id: ${id}`);
|
|
2183
2309
|
}
|
|
2184
|
-
return
|
|
2310
|
+
return join7(PLIST_DIR, `${LABEL_PREFIX}${id}.plist`);
|
|
2185
2311
|
}
|
|
2186
2312
|
function buildPlist(entry) {
|
|
2187
2313
|
const calendars = translateToLaunchd(entry.cron);
|
|
@@ -2217,9 +2343,9 @@ ${fields}
|
|
|
2217
2343
|
` <string>/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin</string>`,
|
|
2218
2344
|
` </dict>`,
|
|
2219
2345
|
` <key>StandardOutPath</key>`,
|
|
2220
|
-
` <string>${escapeXml(
|
|
2346
|
+
` <string>${escapeXml(join7(homedir5(), ".cache", "task", "launchd-stdout.log"))}</string>`,
|
|
2221
2347
|
` <key>StandardErrorPath</key>`,
|
|
2222
|
-
` <string>${escapeXml(
|
|
2348
|
+
` <string>${escapeXml(join7(homedir5(), ".cache", "task", "launchd-stderr.log"))}</string>`,
|
|
2223
2349
|
!entry.enabled ? ` <key>Disabled</key>
|
|
2224
2350
|
<true/>` : "",
|
|
2225
2351
|
"</dict>",
|
|
@@ -2237,9 +2363,9 @@ function bootstrapDomain() {
|
|
|
2237
2363
|
}
|
|
2238
2364
|
var launchdAdapter = {
|
|
2239
2365
|
async upsert(entry) {
|
|
2240
|
-
await
|
|
2366
|
+
await mkdir6(PLIST_DIR, { recursive: true });
|
|
2241
2367
|
const path = plistPath(entry.id);
|
|
2242
|
-
await
|
|
2368
|
+
await writeFile7(path, buildPlist(entry));
|
|
2243
2369
|
try {
|
|
2244
2370
|
execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
|
|
2245
2371
|
} catch {
|
|
@@ -2268,7 +2394,7 @@ var launchdAdapter = {
|
|
|
2268
2394
|
for (const file of ours) {
|
|
2269
2395
|
const id = file.slice(LABEL_PREFIX.length, -".plist".length);
|
|
2270
2396
|
try {
|
|
2271
|
-
const xml = await readFile5(
|
|
2397
|
+
const xml = await readFile5(join7(PLIST_DIR, file), "utf8");
|
|
2272
2398
|
const cron = xml.match(/<key>StartCalendarInterval<\/key>[\s\S]*?<\/array>/)?.[0] ?? "";
|
|
2273
2399
|
const command = xml.match(/<key>ProgramArguments<\/key>\s*<array>([\s\S]*?)<\/array>/)?.[1] ?? "";
|
|
2274
2400
|
const disabled = /<key>Disabled<\/key>\s*<true\/>/.test(xml);
|
|
@@ -2314,7 +2440,7 @@ var launchdAdapter = {
|
|
|
2314
2440
|
}
|
|
2315
2441
|
if (enabled) {
|
|
2316
2442
|
xml = xml.replace(/\s*<key>Disabled<\/key>\s*<true\/>/, "");
|
|
2317
|
-
await
|
|
2443
|
+
await writeFile7(path, xml);
|
|
2318
2444
|
try {
|
|
2319
2445
|
execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
|
|
2320
2446
|
} catch {
|
|
@@ -2326,7 +2452,7 @@ var launchdAdapter = {
|
|
|
2326
2452
|
"</dict>\n</plist>",
|
|
2327
2453
|
" <key>Disabled</key>\n <true/>\n</dict>\n</plist>"
|
|
2328
2454
|
);
|
|
2329
|
-
await
|
|
2455
|
+
await writeFile7(path, xml);
|
|
2330
2456
|
}
|
|
2331
2457
|
try {
|
|
2332
2458
|
execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
|
|
@@ -2679,10 +2805,10 @@ var unsupportedAdapter = {
|
|
|
2679
2805
|
};
|
|
2680
2806
|
|
|
2681
2807
|
// src/scheduler/registry.ts
|
|
2682
|
-
import { mkdir as
|
|
2683
|
-
import { homedir as
|
|
2684
|
-
import { dirname as dirname4, join as
|
|
2685
|
-
var REGISTRY_PATH =
|
|
2808
|
+
import { mkdir as mkdir7, readFile as readFile6, writeFile as writeFile8 } from "fs/promises";
|
|
2809
|
+
import { homedir as homedir6 } from "os";
|
|
2810
|
+
import { dirname as dirname4, join as join8 } from "path";
|
|
2811
|
+
var REGISTRY_PATH = join8(homedir6(), ".config", "task", "schedules.json");
|
|
2686
2812
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2687
2813
|
function looksLikeRegistryRow(value) {
|
|
2688
2814
|
if (!value || typeof value !== "object") return false;
|
|
@@ -2702,8 +2828,8 @@ async function readRegistry() {
|
|
|
2702
2828
|
}
|
|
2703
2829
|
}
|
|
2704
2830
|
async function writeRegistry(rows) {
|
|
2705
|
-
await
|
|
2706
|
-
await
|
|
2831
|
+
await mkdir7(dirname4(REGISTRY_PATH), { recursive: true });
|
|
2832
|
+
await writeFile8(REGISTRY_PATH, JSON.stringify(rows, null, 2));
|
|
2707
2833
|
}
|
|
2708
2834
|
async function upsertRegistry(row) {
|
|
2709
2835
|
if (!UUID_RE.test(row.id)) {
|
|
@@ -2943,8 +3069,8 @@ function stripAnsi(s) {
|
|
|
2943
3069
|
|
|
2944
3070
|
// src/commands/runs.ts
|
|
2945
3071
|
import { readFile as readFile7 } from "fs/promises";
|
|
2946
|
-
import { homedir as
|
|
2947
|
-
import { join as
|
|
3072
|
+
import { homedir as homedir7 } from "os";
|
|
3073
|
+
import { join as join9 } from "path";
|
|
2948
3074
|
function registerRuns(program2) {
|
|
2949
3075
|
const cmd = program2.command("runs").description("Inspect agentic CLI run history");
|
|
2950
3076
|
cmd.command("list").description("List recent runs").option("--limit <n>", "Max rows", "50").option("--ticket <id>", "Filter by ticket").option("--schedule <id>", "Filter by schedule").action(async (opts) => {
|
|
@@ -2973,7 +3099,7 @@ function registerRuns(program2) {
|
|
|
2973
3099
|
process.stdout.write(JSON.stringify(row, null, 2) + "\n");
|
|
2974
3100
|
});
|
|
2975
3101
|
cmd.command("logs <id>").description("Show captured agent output for a run, if available").action(async (id) => {
|
|
2976
|
-
const localPath =
|
|
3102
|
+
const localPath = join9(homedir7(), ".cache", "task", "runs", `${id}.log`);
|
|
2977
3103
|
try {
|
|
2978
3104
|
const text = await readFile7(localPath, "utf8");
|
|
2979
3105
|
process.stdout.write(text);
|
|
@@ -3125,7 +3251,7 @@ function checkBinary(name, command) {
|
|
|
3125
3251
|
}
|
|
3126
3252
|
|
|
3127
3253
|
// src/commands/version.ts
|
|
3128
|
-
var CLI_VERSION = true ? "0.1.
|
|
3254
|
+
var CLI_VERSION = true ? "0.1.4" : "0.0.0-dev";
|
|
3129
3255
|
function registerVersion(program2) {
|
|
3130
3256
|
program2.command("version").description("Print the CLI version").action(() => {
|
|
3131
3257
|
process.stdout.write(CLI_VERSION + "\n");
|