getaura 0.1.4 → 0.1.6
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 +1 -1
- package/dist/index.js +145 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ To install the `aura` command yourself: `npm install -g getaura`. Without it, us
|
|
|
25
25
|
## What you get
|
|
26
26
|
|
|
27
27
|
- **An Aura score** from deterministic checks across security, agent setup, foundations and structure, explained in plain language.
|
|
28
|
-
- **Next steps** in priority order
|
|
28
|
+
- **Next steps** in priority order. After a scan (or with `aura next`), tick the ones you want in the terminal and Aura does them.
|
|
29
29
|
- **Fixes as pull requests you approve**: `aura apply foundation` puts your brief, agent rules, skills, CI and env example in place in one PR, and `aura fix <finding>` has Aura's agent make code changes on a branch.
|
|
30
30
|
- **An agent that keeps it that way**: the rules and skills Aura installs teach your coding agent your standards, and GitHub Actions re-scans every push.
|
|
31
31
|
|
package/dist/index.js
CHANGED
|
@@ -990,10 +990,10 @@ function mergeDefs(...defs) {
|
|
|
990
990
|
function cloneDef(schema) {
|
|
991
991
|
return mergeDefs(schema._zod.def);
|
|
992
992
|
}
|
|
993
|
-
function getElementAtPath(obj,
|
|
994
|
-
if (!
|
|
993
|
+
function getElementAtPath(obj, path22) {
|
|
994
|
+
if (!path22)
|
|
995
995
|
return obj;
|
|
996
|
-
return
|
|
996
|
+
return path22.reduce((acc, key) => acc?.[key], obj);
|
|
997
997
|
}
|
|
998
998
|
function promiseAllObject(promisesObj) {
|
|
999
999
|
const keys = Object.keys(promisesObj);
|
|
@@ -1333,11 +1333,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1333
1333
|
}
|
|
1334
1334
|
return false;
|
|
1335
1335
|
}
|
|
1336
|
-
function prefixIssues(
|
|
1336
|
+
function prefixIssues(path22, issues) {
|
|
1337
1337
|
return issues.map((iss) => {
|
|
1338
1338
|
var _a3;
|
|
1339
1339
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1340
|
-
iss.path.unshift(
|
|
1340
|
+
iss.path.unshift(path22);
|
|
1341
1341
|
return iss;
|
|
1342
1342
|
});
|
|
1343
1343
|
}
|
|
@@ -1787,16 +1787,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
1787
1787
|
}
|
|
1788
1788
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
1789
1789
|
const fieldErrors = { _errors: [] };
|
|
1790
|
-
const processError = (error63,
|
|
1790
|
+
const processError = (error63, path22 = []) => {
|
|
1791
1791
|
for (const issue2 of error63.issues) {
|
|
1792
1792
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1793
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1793
|
+
issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
|
|
1794
1794
|
} else if (issue2.code === "invalid_key") {
|
|
1795
|
-
processError({ issues: issue2.issues }, [...
|
|
1795
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
1796
1796
|
} else if (issue2.code === "invalid_element") {
|
|
1797
|
-
processError({ issues: issue2.issues }, [...
|
|
1797
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
1798
1798
|
} else {
|
|
1799
|
-
const fullpath = [...
|
|
1799
|
+
const fullpath = [...path22, ...issue2.path];
|
|
1800
1800
|
if (fullpath.length === 0) {
|
|
1801
1801
|
fieldErrors._errors.push(mapper(issue2));
|
|
1802
1802
|
} else {
|
|
@@ -1835,17 +1835,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
1835
1835
|
}
|
|
1836
1836
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
1837
1837
|
const result = { errors: [] };
|
|
1838
|
-
const processError = (error63,
|
|
1838
|
+
const processError = (error63, path22 = []) => {
|
|
1839
1839
|
var _a3;
|
|
1840
1840
|
for (const issue2 of error63.issues) {
|
|
1841
1841
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1842
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1842
|
+
issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
|
|
1843
1843
|
} else if (issue2.code === "invalid_key") {
|
|
1844
|
-
processError({ issues: issue2.issues }, [...
|
|
1844
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
1845
1845
|
} else if (issue2.code === "invalid_element") {
|
|
1846
|
-
processError({ issues: issue2.issues }, [...
|
|
1846
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
1847
1847
|
} else {
|
|
1848
|
-
const fullpath = [...
|
|
1848
|
+
const fullpath = [...path22, ...issue2.path];
|
|
1849
1849
|
if (fullpath.length === 0) {
|
|
1850
1850
|
result.errors.push(mapper(issue2));
|
|
1851
1851
|
continue;
|
|
@@ -1884,8 +1884,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
1884
1884
|
}
|
|
1885
1885
|
function toDotPath(_path) {
|
|
1886
1886
|
const segs = [];
|
|
1887
|
-
const
|
|
1888
|
-
for (const seg of
|
|
1887
|
+
const path22 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1888
|
+
for (const seg of path22) {
|
|
1889
1889
|
if (typeof seg === "number")
|
|
1890
1890
|
segs.push(`[${seg}]`);
|
|
1891
1891
|
else if (typeof seg === "symbol")
|
|
@@ -18987,13 +18987,13 @@ function resolveRef(ref, ctx) {
|
|
|
18987
18987
|
if (!ref.startsWith("#")) {
|
|
18988
18988
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
18989
18989
|
}
|
|
18990
|
-
const
|
|
18991
|
-
if (
|
|
18990
|
+
const path22 = ref.slice(1).split("/").filter(Boolean);
|
|
18991
|
+
if (path22.length === 0) {
|
|
18992
18992
|
return ctx.rootSchema;
|
|
18993
18993
|
}
|
|
18994
18994
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
18995
|
-
if (
|
|
18996
|
-
const key =
|
|
18995
|
+
if (path22[0] === defsKey) {
|
|
18996
|
+
const key = path22[1] === void 0 ? void 0 : decodeJSONPointerSegment(path22[1]);
|
|
18997
18997
|
if (!key || !ctx.defs[key]) {
|
|
18998
18998
|
throw new Error(`Reference not found: ${ref}`);
|
|
18999
18999
|
}
|
|
@@ -20429,7 +20429,7 @@ function pmCommands(pm) {
|
|
|
20429
20429
|
// package.json
|
|
20430
20430
|
var package_default = {
|
|
20431
20431
|
name: "getaura",
|
|
20432
|
-
version: "0.1.
|
|
20432
|
+
version: "0.1.6",
|
|
20433
20433
|
description: "Aura helps you and your coding agent follow best practices while you vibe code.",
|
|
20434
20434
|
type: "module",
|
|
20435
20435
|
bin: {
|
|
@@ -21545,7 +21545,7 @@ var AuraClient = class _AuraClient {
|
|
|
21545
21545
|
get hasKey() {
|
|
21546
21546
|
return Boolean(this.key);
|
|
21547
21547
|
}
|
|
21548
|
-
async request(method,
|
|
21548
|
+
async request(method, path22, body, timeoutMs = 6e4) {
|
|
21549
21549
|
if (!this.key) throw new AuraApiError("no_key", "No pilot key");
|
|
21550
21550
|
let payload;
|
|
21551
21551
|
if (body !== void 0) {
|
|
@@ -21555,7 +21555,7 @@ var AuraClient = class _AuraClient {
|
|
|
21555
21555
|
}
|
|
21556
21556
|
let res;
|
|
21557
21557
|
try {
|
|
21558
|
-
res = await fetch(`${this.baseUrl}/v1/${
|
|
21558
|
+
res = await fetch(`${this.baseUrl}/v1/${path22}`, {
|
|
21559
21559
|
method,
|
|
21560
21560
|
headers: { authorization: `Bearer ${this.key}`, "content-type": "application/json", "user-agent": `getaura/${AURA_VERSION}` },
|
|
21561
21561
|
body: payload,
|
|
@@ -21857,8 +21857,8 @@ var typecheck = {
|
|
|
21857
21857
|
async run(ctx) {
|
|
21858
21858
|
if (ctx.options.fast) return { status: "unknown", summary: "Skipped in fast mode." };
|
|
21859
21859
|
const { existsSync: existsSync17 } = await import("fs");
|
|
21860
|
-
const
|
|
21861
|
-
const tsc =
|
|
21860
|
+
const path22 = await import("path");
|
|
21861
|
+
const tsc = path22.join(ctx.root, "node_modules", ".bin", process.platform === "win32" ? "tsc.cmd" : "tsc");
|
|
21862
21862
|
if (!existsSync17(tsc)) return { status: "unknown", summary: "Dependencies not installed, so the type check was skipped." };
|
|
21863
21863
|
const r = await run(tsc, ["--noEmit", "--pretty", "false"], { cwd: ctx.root, timeoutMs: 18e4 });
|
|
21864
21864
|
if (r.timedOut) return { status: "unknown", summary: "Type check timed out." };
|
|
@@ -23394,6 +23394,53 @@ function explainSignIn(outcome) {
|
|
|
23394
23394
|
}
|
|
23395
23395
|
}
|
|
23396
23396
|
|
|
23397
|
+
// src/commands/pick-steps.ts
|
|
23398
|
+
function stepRun(step, hasKey) {
|
|
23399
|
+
const [, sub, arg = step.actionId] = step.command.split(" ");
|
|
23400
|
+
if (sub === "apply") return { kind: "apply", actionId: arg };
|
|
23401
|
+
if (sub === "fix") return { kind: "fix", actionId: arg, withOwnAgent: !hasKey };
|
|
23402
|
+
if (sub === "guide") return { kind: "guide", topic: arg };
|
|
23403
|
+
return { kind: "inventory" };
|
|
23404
|
+
}
|
|
23405
|
+
function hint(step, hasKey) {
|
|
23406
|
+
const run2 = stepRun(step, hasKey);
|
|
23407
|
+
const what = run2.kind === "apply" ? "opens a pull request" : run2.kind === "fix" ? run2.withOwnAgent ? "writes a task for your coding agent" : "Aura\u2019s agent fixes it in a pull request" : run2.kind === "guide" ? "shows step-by-step instructions" : "a few questions";
|
|
23408
|
+
return [what, step.impact > 0 ? `+${step.impact} points` : "", effortLabel(step.effort)].filter(Boolean).join(" \xB7 ");
|
|
23409
|
+
}
|
|
23410
|
+
async function pickAndRunSteps(steps, limit = 10) {
|
|
23411
|
+
if (steps.length === 0) {
|
|
23412
|
+
console.log(pc.green("\n Nothing to do right now."));
|
|
23413
|
+
return 0;
|
|
23414
|
+
}
|
|
23415
|
+
const hasKey = Boolean(getApiKey());
|
|
23416
|
+
console.log("");
|
|
23417
|
+
const chosen = unwrap(
|
|
23418
|
+
await p.multiselect({
|
|
23419
|
+
message: "Next steps: pick what Aura should do now (space to select, enter to confirm, enter with none to skip)",
|
|
23420
|
+
options: steps.slice(0, limit).map((s) => ({ value: s.actionId, label: s.title, hint: hint(s, hasKey) })),
|
|
23421
|
+
required: false
|
|
23422
|
+
})
|
|
23423
|
+
);
|
|
23424
|
+
if (chosen.length === 0) {
|
|
23425
|
+
say.dim("Nothing selected. Run `aura next` any time to pick again.");
|
|
23426
|
+
return 0;
|
|
23427
|
+
}
|
|
23428
|
+
const results = [];
|
|
23429
|
+
for (const step of steps.filter((s) => chosen.includes(s.actionId))) {
|
|
23430
|
+
console.log(`
|
|
23431
|
+
${pc.magenta("\u2726")} ${pc.bold(step.title)}`);
|
|
23432
|
+
const run2 = stepRun(step, hasKey);
|
|
23433
|
+
const code = run2.kind === "apply" ? await applyCommand(run2.actionId, { yes: true }) : run2.kind === "fix" ? await fixCommand(run2.actionId, run2.withOwnAgent ? { agent: true } : { yes: true }) : run2.kind === "guide" ? await guideCommand(run2.topic, {}) : await inventoryCommand({});
|
|
23434
|
+
results.push({ title: step.title, ok: code === 0 });
|
|
23435
|
+
}
|
|
23436
|
+
if (results.length > 1) {
|
|
23437
|
+
console.log(`
|
|
23438
|
+
${pc.bold(" Done")}`);
|
|
23439
|
+
for (const r of results) console.log(` ${r.ok ? pc.green("\u2714") : pc.red("\u2716")} ${r.title}`);
|
|
23440
|
+
}
|
|
23441
|
+
return results.every((r) => r.ok) ? 0 : 1;
|
|
23442
|
+
}
|
|
23443
|
+
|
|
23397
23444
|
// src/commands/simple.ts
|
|
23398
23445
|
async function latestScan(root) {
|
|
23399
23446
|
const file2 = auraPath(root, "scan.json");
|
|
@@ -23412,8 +23459,10 @@ async function nextCommand(flags) {
|
|
|
23412
23459
|
const root = await findRepoRoot();
|
|
23413
23460
|
const scan = await latestScan(root);
|
|
23414
23461
|
const steps = nextSteps(scan, { includeFoundationBundle: true, accounts: accountState(root, scan.stack.services) });
|
|
23462
|
+
const limit = flags.limit ? Number(flags.limit) : 10;
|
|
23415
23463
|
if (flags.json) printJson({ score: scan.score, nextSteps: steps });
|
|
23416
|
-
else
|
|
23464
|
+
else if (interactive()) return pickAndRunSteps(steps, limit);
|
|
23465
|
+
else console.log(renderNextSteps(steps, limit));
|
|
23417
23466
|
return 0;
|
|
23418
23467
|
}
|
|
23419
23468
|
async function historyCommand(flags) {
|
|
@@ -23970,7 +24019,7 @@ async function undoPlan(root, plan) {
|
|
|
23970
24019
|
|
|
23971
24020
|
// src/commands/init.ts
|
|
23972
24021
|
import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
|
|
23973
|
-
import { spawnSync as
|
|
24022
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
23974
24023
|
|
|
23975
24024
|
// src/brief.ts
|
|
23976
24025
|
import path18 from "path";
|
|
@@ -24061,6 +24110,7 @@ async function draftBrief(client, answers, summary) {
|
|
|
24061
24110
|
}
|
|
24062
24111
|
|
|
24063
24112
|
// src/core/aura-command.ts
|
|
24113
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
24064
24114
|
function hasAuraCommand() {
|
|
24065
24115
|
return commandExists("aura");
|
|
24066
24116
|
}
|
|
@@ -24070,6 +24120,10 @@ async function installAuraCommand() {
|
|
|
24070
24120
|
if (r.code !== 0) return { ok: false, needsAdmin: /EACCES|EPERM|permission denied/i.test(r.stderr + r.stdout) };
|
|
24071
24121
|
return { ok: true, onPath: await hasAuraCommand() };
|
|
24072
24122
|
}
|
|
24123
|
+
async function installWithSudo() {
|
|
24124
|
+
const r = spawnSync2("sudo", ["npm", "install", "-g", `getaura@${AURA_VERSION}`], { stdio: "inherit" });
|
|
24125
|
+
return r.status === 0 && await hasAuraCommand();
|
|
24126
|
+
}
|
|
24073
24127
|
function installFallback(result, platform = process.platform) {
|
|
24074
24128
|
const admin = result.needsAdmin && platform !== "win32" ? `Run \`sudo ${INSTALL_AURA}\` and enter your computer password, or use` : "Use";
|
|
24075
24129
|
return `${admin} \`npx getaura <command>\` in place of \`aura <command>\` (for example \`npx getaura scan\`).`;
|
|
@@ -24140,13 +24194,15 @@ async function scanCommand(flags) {
|
|
|
24140
24194
|
return exitCode;
|
|
24141
24195
|
}
|
|
24142
24196
|
console.log(renderTerminal(scan, { previous: flags.ci ? base?.score ?? null : previous }));
|
|
24143
|
-
|
|
24197
|
+
const pick2 = !flags.ci && interactive();
|
|
24198
|
+
if (!flags.ci && !pick2) console.log(renderNextSteps(steps, 3));
|
|
24144
24199
|
say.dim(
|
|
24145
24200
|
`
|
|
24146
24201
|
Full report: .aura/report.md${client.hasKey || flags.explain === false ? "" : " \xB7 Add a pilot key (aura login) for plain-language explanations."}`
|
|
24147
24202
|
);
|
|
24148
24203
|
if (base) say.info(`
|
|
24149
24204
|
Compared with ${flags.base}: ${base.score} \u2192 ${scan.score}${exitCode ? ` (dropped more than ${maxDrop})` : ""}`);
|
|
24205
|
+
if (pick2) await pickAndRunSteps(steps);
|
|
24150
24206
|
return exitCode;
|
|
24151
24207
|
}
|
|
24152
24208
|
|
|
@@ -24162,7 +24218,7 @@ function detectAgents(root) {
|
|
|
24162
24218
|
}
|
|
24163
24219
|
function openEditor(file2) {
|
|
24164
24220
|
const editor = process.env.VISUAL || process.env.EDITOR || (process.platform === "win32" ? "notepad" : "nano");
|
|
24165
|
-
const r =
|
|
24221
|
+
const r = spawnSync3(editor, [file2], { stdio: "inherit", shell: process.platform === "win32" });
|
|
24166
24222
|
return r.status === 0;
|
|
24167
24223
|
}
|
|
24168
24224
|
var EXAMPLE_ANSWERS = '{"whatItDoes": "\u2026", "audience": "\u2026", "chargesMoney": false, "dataHandled": ["personal"], "userRegions": ["Canada"]}';
|
|
@@ -24354,7 +24410,10 @@ async function initCommand(flags) {
|
|
|
24354
24410
|
s.stop(installed.onPath ? "Installed. Run `aura scan` from any folder." : "Installed. Open a new terminal window, then run `aura scan`.");
|
|
24355
24411
|
else {
|
|
24356
24412
|
s.stop("Couldn\u2019t install the aura command");
|
|
24357
|
-
|
|
24413
|
+
const useSudo = installed.needsAdmin && process.platform !== "win32" && unwrap(await p.confirm({ message: "Your computer needs your password to install it. Enter your password now?", initialValue: true }));
|
|
24414
|
+
if (!useSudo) say.warn(installFallback(installed));
|
|
24415
|
+
else if (await installWithSudo()) say.ok("Installed. Run `aura scan` from any folder.");
|
|
24416
|
+
else say.warn(installFallback({ needsAdmin: false }));
|
|
24358
24417
|
}
|
|
24359
24418
|
} else say.dim(`Use \`npx getaura <command>\` instead, or install it later with \`${INSTALL_AURA}\`.`);
|
|
24360
24419
|
} else {
|
|
@@ -24474,10 +24533,62 @@ ${body}`);
|
|
|
24474
24533
|
return 0;
|
|
24475
24534
|
}
|
|
24476
24535
|
|
|
24536
|
+
// src/index.ts
|
|
24537
|
+
import pc4 from "picocolors";
|
|
24538
|
+
|
|
24539
|
+
// src/core/update-check.ts
|
|
24540
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
|
|
24541
|
+
import os6 from "os";
|
|
24542
|
+
import path21 from "path";
|
|
24543
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
24544
|
+
var cacheFile = () => path21.join(os6.homedir(), ".aura", "update-check.json");
|
|
24545
|
+
function isNewer(a, b) {
|
|
24546
|
+
if (!/^\d+\.\d+\.\d+$/.test(a) || !/^\d+\.\d+\.\d+$/.test(b)) return false;
|
|
24547
|
+
const [x, y] = [a, b].map((v) => v.split(".").map(Number));
|
|
24548
|
+
for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] > y[i];
|
|
24549
|
+
return false;
|
|
24550
|
+
}
|
|
24551
|
+
async function fetchLatest() {
|
|
24552
|
+
try {
|
|
24553
|
+
const res = await fetch("https://registry.npmjs.org/getaura/latest", { signal: AbortSignal.timeout(1500) });
|
|
24554
|
+
const body = await res.json();
|
|
24555
|
+
return res.ok && typeof body.version === "string" ? body.version : null;
|
|
24556
|
+
} catch {
|
|
24557
|
+
return null;
|
|
24558
|
+
}
|
|
24559
|
+
}
|
|
24560
|
+
async function newerVersion(opts = {}) {
|
|
24561
|
+
const now = opts.now ?? Date.now();
|
|
24562
|
+
let latest = null;
|
|
24563
|
+
try {
|
|
24564
|
+
const cached2 = JSON.parse(readFileSync16(cacheFile(), "utf8"));
|
|
24565
|
+
if (now - cached2.checkedAt < DAY_MS) latest = cached2.latest;
|
|
24566
|
+
else throw new Error("stale");
|
|
24567
|
+
} catch {
|
|
24568
|
+
latest = await (opts.fetchLatest ?? fetchLatest)();
|
|
24569
|
+
try {
|
|
24570
|
+
mkdirSync6(path21.dirname(cacheFile()), { recursive: true });
|
|
24571
|
+
writeFileSync8(cacheFile(), JSON.stringify({ checkedAt: now, latest }));
|
|
24572
|
+
} catch {
|
|
24573
|
+
}
|
|
24574
|
+
}
|
|
24575
|
+
return latest && isNewer(latest, opts.current ?? AURA_VERSION) ? latest : null;
|
|
24576
|
+
}
|
|
24577
|
+
function startUpdateCheck() {
|
|
24578
|
+
if (!process.stdout.isTTY || process.env.CI || process.env.AURA_NO_UPDATE_CHECK) return Promise.resolve(null);
|
|
24579
|
+
return newerVersion().catch(() => null);
|
|
24580
|
+
}
|
|
24581
|
+
function updateNotice(latest, argv1 = process.argv[1] ?? "") {
|
|
24582
|
+
const viaNpx = /[\\/]_npx[\\/]/.test(argv1);
|
|
24583
|
+
const how = viaNpx ? "use `npx getaura@latest`" : "update with `npm install -g getaura@latest`";
|
|
24584
|
+
return `Aura ${latest} is available (you have ${AURA_VERSION}): ${how}.`;
|
|
24585
|
+
}
|
|
24586
|
+
|
|
24477
24587
|
// src/index.ts
|
|
24478
24588
|
var program = new Command();
|
|
24479
24589
|
program.name("aura").description("Aura helps you and your coding agent follow best practices while you vibe code.").version(AURA_VERSION).showHelpAfterError();
|
|
24480
24590
|
program.addHelpText("before", () => interactive() ? banner() : "");
|
|
24591
|
+
var update = startUpdateCheck();
|
|
24481
24592
|
function action(fn) {
|
|
24482
24593
|
return async (...args) => {
|
|
24483
24594
|
try {
|
|
@@ -24491,6 +24602,9 @@ function action(fn) {
|
|
|
24491
24602
|
if (process.env.AURA_DEBUG) console.error(err);
|
|
24492
24603
|
process.exitCode = 1;
|
|
24493
24604
|
}
|
|
24605
|
+
const latest = await update;
|
|
24606
|
+
if (latest) console.error(pc4.dim(`
|
|
24607
|
+
${updateNotice(latest)}`));
|
|
24494
24608
|
};
|
|
24495
24609
|
}
|
|
24496
24610
|
program.command("init").description("Set up Aura: pick your agent, write the product brief, install the Aura skill and run the first scan").option("--agent <id...>", "coding agent(s): claude, codex, cursor, pi").option("-y, --yes", "no prompts; use detected defaults").option("--key <key>", "Aura pilot key, for CI and scripts (otherwise a browser page asks for it)").option("--wait <seconds>", "how long to wait for the browser sign-in (default: until the link expires; 90 for agents)").option("--brief-file <path>", "use this file as the product brief").option("--answers <path>", "JSON file with the setup answers").option("--no-scan", "skip the first scan").addOption(new Option("--telemetry", "share scores and action names with the Aura team")).addOption(new Option("--no-telemetry", "don\u2019t share anything")).action(action((flags) => initCommand(flags)));
|