getaura 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/README.md +3 -1
- package/dist/index.js +67 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,9 @@ Your agent runs the setup and sends you a link to connect your pilot key in the
|
|
|
18
18
|
npx getaura init
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
`init` checks git and the GitHub CLI, asks which coding agent you use, opens your browser to connect your pilot key, drafts your product brief, installs the Aura skill and runs your first scan.
|
|
21
|
+
`init` checks git and the GitHub CLI, asks which coding agent you use, opens your browser to connect your pilot key, drafts your product brief, installs the Aura skill, offers to install the `aura` command and runs your first scan. After that, run `aura scan` from any folder.
|
|
22
|
+
|
|
23
|
+
To install the `aura` command yourself: `npm install -g getaura`. Without it, use `npx getaura <command>` (for example `npx getaura scan`).
|
|
22
24
|
|
|
23
25
|
## What you get
|
|
24
26
|
|
package/dist/index.js
CHANGED
|
@@ -20031,16 +20031,20 @@ import { fileURLToPath } from "url";
|
|
|
20031
20031
|
|
|
20032
20032
|
// src/core/exec.ts
|
|
20033
20033
|
import { spawn, spawnSync } from "child_process";
|
|
20034
|
+
var WINDOWS_PROGRAMS = /* @__PURE__ */ new Set(["git", "gh", "node", "tar", "where"]);
|
|
20035
|
+
function quoteForCmd(arg) {
|
|
20036
|
+
return /^[\w@%+=:,./\\-]+$/.test(arg) ? arg : `"${arg.replace(/"/g, '\\"')}"`;
|
|
20037
|
+
}
|
|
20038
|
+
function spawnPlan(cmd, args, platform = process.platform) {
|
|
20039
|
+
const direct = platform !== "win32" || cmd.includes("/") || cmd.includes("\\") || WINDOWS_PROGRAMS.has(cmd.toLowerCase());
|
|
20040
|
+
return direct ? { args, shell: false } : { args: args.map(quoteForCmd), shell: true };
|
|
20041
|
+
}
|
|
20034
20042
|
function run(cmd, args, opts = {}) {
|
|
20035
20043
|
return new Promise((resolve) => {
|
|
20036
20044
|
let child;
|
|
20037
20045
|
try {
|
|
20038
|
-
|
|
20039
|
-
|
|
20040
|
-
env: opts.env ?? process.env,
|
|
20041
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
20042
|
-
shell: process.platform === "win32" && !cmd.includes("/") && !cmd.includes("\\")
|
|
20043
|
-
});
|
|
20046
|
+
const plan = spawnPlan(cmd, args);
|
|
20047
|
+
child = spawn(cmd, plan.args, { cwd: opts.cwd, env: opts.env ?? process.env, stdio: ["pipe", "pipe", "pipe"], shell: plan.shell });
|
|
20044
20048
|
} catch (err) {
|
|
20045
20049
|
resolve({ code: 127, stdout: "", stderr: String(err) });
|
|
20046
20050
|
return;
|
|
@@ -20076,7 +20080,11 @@ var AURA_DIR = ".aura";
|
|
|
20076
20080
|
var ALWAYS_IGNORED = ["node_modules", ".next", ".git", "dist", "build", "out", ".vercel", ".turbo", "coverage", ".aura"];
|
|
20077
20081
|
async function findRepoRoot(cwd = process.cwd()) {
|
|
20078
20082
|
const r = await run("git", ["rev-parse", "--show-toplevel"], { cwd });
|
|
20079
|
-
return r.code === 0 ? r.stdout.trim() : cwd;
|
|
20083
|
+
return path.resolve(r.code === 0 ? r.stdout.trim() : cwd);
|
|
20084
|
+
}
|
|
20085
|
+
function isInside(root, full, p2 = path) {
|
|
20086
|
+
const rel = p2.relative(p2.resolve(root), p2.resolve(full));
|
|
20087
|
+
return rel !== "" && rel !== ".." && !rel.startsWith(`..${p2.sep}`) && !p2.isAbsolute(rel);
|
|
20080
20088
|
}
|
|
20081
20089
|
async function isGitRepo(cwd) {
|
|
20082
20090
|
return (await run("git", ["rev-parse", "--is-inside-work-tree"], { cwd })).code === 0;
|
|
@@ -20421,7 +20429,7 @@ function pmCommands(pm) {
|
|
|
20421
20429
|
// package.json
|
|
20422
20430
|
var package_default = {
|
|
20423
20431
|
name: "getaura",
|
|
20424
|
-
version: "0.1.
|
|
20432
|
+
version: "0.1.4",
|
|
20425
20433
|
description: "Aura helps you and your coding agent follow best practices while you vibe code.",
|
|
20426
20434
|
type: "module",
|
|
20427
20435
|
bin: {
|
|
@@ -21591,6 +21599,10 @@ import path9 from "path";
|
|
|
21591
21599
|
async function git(root, ...args) {
|
|
21592
21600
|
return run("git", args, { cwd: root });
|
|
21593
21601
|
}
|
|
21602
|
+
function ghInstallHint(platform = process.platform) {
|
|
21603
|
+
const how = platform === "win32" ? "Install it with `winget install --id GitHub.cli`" : platform === "darwin" ? "Install it with `brew install gh` (or download it from https://cli.github.com)" : "Install it from https://cli.github.com";
|
|
21604
|
+
return `${how}, open a new terminal, then run \`gh auth login\`.`;
|
|
21605
|
+
}
|
|
21594
21606
|
async function ghStatus(root) {
|
|
21595
21607
|
const v = await run("gh", ["--version"]);
|
|
21596
21608
|
if (v.code !== 0) return { installed: false, authed: false, hasRemote: false };
|
|
@@ -21618,7 +21630,7 @@ async function freeBranchName(root, base) {
|
|
|
21618
21630
|
function writeChanges(root, changes) {
|
|
21619
21631
|
for (const c of changes) {
|
|
21620
21632
|
const full = path9.join(root, c.path);
|
|
21621
|
-
if (!
|
|
21633
|
+
if (!isInside(root, full)) throw new Error(`Refusing to write outside the repo: ${c.path}`);
|
|
21622
21634
|
if (c.content === null) rmSync(full, { force: true });
|
|
21623
21635
|
else {
|
|
21624
21636
|
mkdirSync2(path9.dirname(full), { recursive: true });
|
|
@@ -22762,7 +22774,7 @@ function safePath(root, rel) {
|
|
|
22762
22774
|
if (normalized.startsWith("../") || normalized === ".." || path13.isAbsolute(normalized)) throw new Error(`Path is outside the repo: ${rel}`);
|
|
22763
22775
|
if (FORBIDDEN.test(normalized)) throw new Error(`Aura doesn\u2019t let the agent touch ${normalized}.`);
|
|
22764
22776
|
const full = path13.join(root, normalized);
|
|
22765
|
-
if (!
|
|
22777
|
+
if (!isInside(root, full)) throw new Error(`Path is outside the repo: ${rel}`);
|
|
22766
22778
|
return normalized;
|
|
22767
22779
|
}
|
|
22768
22780
|
function clip(text) {
|
|
@@ -23845,7 +23857,7 @@ ${pc.bold(action2.title)}`);
|
|
|
23845
23857
|
const gh = await ghStatus(root);
|
|
23846
23858
|
if (!gh.installed || !gh.authed || !gh.hasRemote) {
|
|
23847
23859
|
say.error(
|
|
23848
|
-
!gh.installed ?
|
|
23860
|
+
!gh.installed ? `The GitHub CLI isn\u2019t installed. ${ghInstallHint()}` : !gh.authed ? "Run `gh auth login` first." : "This repo has no GitHub remote. Push it to GitHub first."
|
|
23849
23861
|
);
|
|
23850
23862
|
say.dim("Or run with --no-pr to commit the change on a local branch.");
|
|
23851
23863
|
return 1;
|
|
@@ -24048,6 +24060,21 @@ async function draftBrief(client, answers, summary) {
|
|
|
24048
24060
|
return res.brief.trim() + "\n";
|
|
24049
24061
|
}
|
|
24050
24062
|
|
|
24063
|
+
// src/core/aura-command.ts
|
|
24064
|
+
function hasAuraCommand() {
|
|
24065
|
+
return commandExists("aura");
|
|
24066
|
+
}
|
|
24067
|
+
var INSTALL_AURA = `npm install -g getaura@${AURA_VERSION}`;
|
|
24068
|
+
async function installAuraCommand() {
|
|
24069
|
+
const r = await run("npm", ["install", "-g", `getaura@${AURA_VERSION}`], { timeoutMs: 18e4 });
|
|
24070
|
+
if (r.code !== 0) return { ok: false, needsAdmin: /EACCES|EPERM|permission denied/i.test(r.stderr + r.stdout) };
|
|
24071
|
+
return { ok: true, onPath: await hasAuraCommand() };
|
|
24072
|
+
}
|
|
24073
|
+
function installFallback(result, platform = process.platform) {
|
|
24074
|
+
const admin = result.needsAdmin && platform !== "win32" ? `Run \`sudo ${INSTALL_AURA}\` and enter your computer password, or use` : "Use";
|
|
24075
|
+
return `${admin} \`npx getaura <command>\` in place of \`aura <command>\` (for example \`npx getaura scan\`).`;
|
|
24076
|
+
}
|
|
24077
|
+
|
|
24051
24078
|
// src/commands/scan.ts
|
|
24052
24079
|
import { mkdtempSync as mkdtempSync3, rmSync as rmSync7, writeFileSync as writeFileSync7 } from "fs";
|
|
24053
24080
|
import os5 from "os";
|
|
@@ -24174,8 +24201,7 @@ async function initCommand(flags) {
|
|
|
24174
24201
|
}
|
|
24175
24202
|
const root = await findRepoRoot(cwd);
|
|
24176
24203
|
const gh = await ghStatus(root);
|
|
24177
|
-
if (!gh.installed)
|
|
24178
|
-
say.warn("The GitHub CLI (gh) isn\u2019t installed. Aura needs it to open pull requests. Run `aura guide install-github-cli`. You can keep going and scan now.");
|
|
24204
|
+
if (!gh.installed) say.warn(`The GitHub CLI (gh) isn\u2019t installed. Aura needs it to open pull requests. ${ghInstallHint()} You can keep going and scan now.`);
|
|
24179
24205
|
else if (!gh.authed) say.warn("The GitHub CLI isn\u2019t signed in. Run `gh auth login` before applying fixes.");
|
|
24180
24206
|
else if (!gh.hasRemote) say.warn("This repo has no GitHub remote yet. Push it to GitHub before applying fixes (`gh repo create`).");
|
|
24181
24207
|
else say.ok("git and the GitHub CLI are ready.");
|
|
@@ -24196,6 +24222,8 @@ async function initCommand(flags) {
|
|
|
24196
24222
|
required: true
|
|
24197
24223
|
})
|
|
24198
24224
|
) : detected.length ? detected : ["claude"];
|
|
24225
|
+
} else {
|
|
24226
|
+
agents = [.../* @__PURE__ */ new Set([...config2.agents, ...agents])];
|
|
24199
24227
|
}
|
|
24200
24228
|
config2.agents = agents;
|
|
24201
24229
|
let key = flags.key ?? getApiKey();
|
|
@@ -24231,10 +24259,11 @@ async function initCommand(flags) {
|
|
|
24231
24259
|
const ctx = await buildContext(root, { fast: true, noDownload: true }, config2);
|
|
24232
24260
|
const briefPath = auraPath(root, "brief.md");
|
|
24233
24261
|
let brief2 = null;
|
|
24262
|
+
let keptBrief = false;
|
|
24234
24263
|
if (flags.briefFile) {
|
|
24235
24264
|
brief2 = readFileSync15(flags.briefFile, "utf8");
|
|
24236
|
-
} else if (existsSync16(briefPath) && !(tty && unwrap(await p.confirm({ message: "A product brief already exists. Draft a new one?", initialValue: false })))) {
|
|
24237
|
-
|
|
24265
|
+
} else if (!flags.answers && existsSync16(briefPath) && !(tty && unwrap(await p.confirm({ message: "A product brief already exists. Draft a new one?", initialValue: false })))) {
|
|
24266
|
+
keptBrief = true;
|
|
24238
24267
|
} else {
|
|
24239
24268
|
let answers = null;
|
|
24240
24269
|
if (flags.answers) {
|
|
@@ -24286,7 +24315,9 @@ async function initCommand(flags) {
|
|
|
24286
24315
|
console.log(briefHandoff());
|
|
24287
24316
|
}
|
|
24288
24317
|
}
|
|
24289
|
-
if (
|
|
24318
|
+
if (keptBrief) {
|
|
24319
|
+
say.ok("Kept your existing product brief (.aura/brief.md).");
|
|
24320
|
+
} else if (brief2) {
|
|
24290
24321
|
writeAuraFile(root, "brief.md", brief2);
|
|
24291
24322
|
if (tty) {
|
|
24292
24323
|
p.note(brief2.split("\n").slice(0, 24).join("\n") + (brief2.split("\n").length > 24 ? "\n\u2026" : ""), "Product brief draft");
|
|
@@ -24313,6 +24344,26 @@ async function initCommand(flags) {
|
|
|
24313
24344
|
}
|
|
24314
24345
|
saveConfig(root, config2);
|
|
24315
24346
|
ensureGitignore(root);
|
|
24347
|
+
if (!process.env.CI && !await hasAuraCommand()) {
|
|
24348
|
+
if (tty) {
|
|
24349
|
+
if (unwrap(await p.confirm({ message: "Install the `aura` command so you can run `aura scan` any time?", initialValue: true }))) {
|
|
24350
|
+
const s = spin(true);
|
|
24351
|
+
s.start("Installing the aura command");
|
|
24352
|
+
const installed = await installAuraCommand();
|
|
24353
|
+
if (installed.ok)
|
|
24354
|
+
s.stop(installed.onPath ? "Installed. Run `aura scan` from any folder." : "Installed. Open a new terminal window, then run `aura scan`.");
|
|
24355
|
+
else {
|
|
24356
|
+
s.stop("Couldn\u2019t install the aura command");
|
|
24357
|
+
say.warn(installFallback(installed));
|
|
24358
|
+
}
|
|
24359
|
+
} else say.dim(`Use \`npx getaura <command>\` instead, or install it later with \`${INSTALL_AURA}\`.`);
|
|
24360
|
+
} else {
|
|
24361
|
+
console.log(`
|
|
24362
|
+
${pc.magenta("\u2726")} ${pc.bold("Give the user the aura command")}`);
|
|
24363
|
+
console.log(` Run \`${INSTALL_AURA}\` so they can type \`aura scan\` from now on. Until then, use \`npx getaura <command>\`.
|
|
24364
|
+
`);
|
|
24365
|
+
}
|
|
24366
|
+
}
|
|
24316
24367
|
if (flags.scan === false) {
|
|
24317
24368
|
if (tty) p.outro("Done. Run `aura scan` when you\u2019re ready.");
|
|
24318
24369
|
return 0;
|