@exposify/cli 0.0.3 → 0.0.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/index.d.ts +9 -0
- package/dist/index.js +27 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ interface ScannedRoute {
|
|
|
23
23
|
exposed: boolean;
|
|
24
24
|
/** Exposed only when listed in `expose`, even a read (core's RouteInfo.optIn), e.g. a Pages Router method detected in code. */
|
|
25
25
|
optIn?: boolean;
|
|
26
|
+
/** Not a tool unless listed in `expose`, so setup leaves it unticked though it's a read: a page that's just a form, a route that finishes a sign-in. */
|
|
27
|
+
offByDefault?: boolean;
|
|
26
28
|
/** "page": an App Router page read as a tool (its HTML, like a browser), not a route handler. */
|
|
27
29
|
kind?: "page";
|
|
28
30
|
reason: string;
|
|
@@ -215,8 +217,13 @@ interface ApplyPlan {
|
|
|
215
217
|
after: string;
|
|
216
218
|
}
|
|
217
219
|
/** Either a plan, or why this one can't be applied safely (setup then prints the paste instructions). */
|
|
220
|
+
/** `also`: edits to other files that go with the plan, each with what to do by hand when it isn't written. */
|
|
218
221
|
type ApplyOutcome = {
|
|
219
222
|
plan: ApplyPlan;
|
|
223
|
+
also?: Array<{
|
|
224
|
+
plan: ApplyPlan;
|
|
225
|
+
manual: string;
|
|
226
|
+
}>;
|
|
220
227
|
} | {
|
|
221
228
|
blocked: string;
|
|
222
229
|
};
|
|
@@ -300,6 +307,8 @@ interface CliAdapter<R extends ScanResult = ScanResult> {
|
|
|
300
307
|
entryExample: string;
|
|
301
308
|
/** What `--entry` names, for the usage text, e.g. "The file that creates your Express app". */
|
|
302
309
|
entryHelp: string;
|
|
310
|
+
/** The adapter's own commands, for the usage text: ["generate", "Writes …"]. Its bin runs them, not runCli. */
|
|
311
|
+
commands?: Array<[name: string, help: string]>;
|
|
303
312
|
locate(cwd: string, entryFlag?: string): AppLocation | undefined;
|
|
304
313
|
scan(location: AppLocation, env: Record<string, string>): Promise<AdapterScanOutcome<R>>;
|
|
305
314
|
/**
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ import { DESCRIPTIONS_FILE, parseDescriptions } from "@exposify/core";
|
|
|
47
47
|
// src/checklist.ts
|
|
48
48
|
var routeKey = (r) => `${r.method} ${r.path}`;
|
|
49
49
|
var isRead = (r) => r.method === "GET" || r.method === "HEAD";
|
|
50
|
+
var readByDefault = (r) => isRead(r) && !r.offByDefault;
|
|
50
51
|
function isLocked(r) {
|
|
51
52
|
return r.marker !== void 0;
|
|
52
53
|
}
|
|
@@ -55,10 +56,10 @@ function initialState(routes, opts) {
|
|
|
55
56
|
const listed = new Set(opts.listedActions ?? []);
|
|
56
57
|
const selected = /* @__PURE__ */ new Set();
|
|
57
58
|
for (const r of routes) {
|
|
58
|
-
const ticked = opts.hasConfig || isLocked(r) ? r.exposed :
|
|
59
|
+
const ticked = opts.hasConfig || isLocked(r) ? r.exposed : readByDefault(r);
|
|
59
60
|
if (ticked) selected.add(routeKey(r));
|
|
60
61
|
}
|
|
61
|
-
const readsOnly = new Set(routes.filter((r) => isLocked(r) ? r.exposed :
|
|
62
|
+
const readsOnly = new Set(routes.filter((r) => isLocked(r) ? r.exposed : readByDefault(r)).map(routeKey));
|
|
62
63
|
return {
|
|
63
64
|
routes,
|
|
64
65
|
selected,
|
|
@@ -130,7 +131,7 @@ function reduce(state, action) {
|
|
|
130
131
|
case "none":
|
|
131
132
|
return setTicks(state, () => false, true);
|
|
132
133
|
case "readsOnly":
|
|
133
|
-
return setTicks(state,
|
|
134
|
+
return setTicks(state, readByDefault, true);
|
|
134
135
|
case "filter":
|
|
135
136
|
return { ...state, filter: action.text, cursor: 0 };
|
|
136
137
|
case "enterNuclear": {
|
|
@@ -1345,14 +1346,18 @@ function openInBrowser(url) {
|
|
|
1345
1346
|
}
|
|
1346
1347
|
|
|
1347
1348
|
// src/run.ts
|
|
1348
|
-
var usage = (bin, entryHelp) => `Usage: ${bin} <command> [options]
|
|
1349
|
+
var usage = ({ bin, entryHelp, commands: commands2 = [] }) => `Usage: ${bin} <command> [options]
|
|
1349
1350
|
|
|
1350
1351
|
Commands:
|
|
1351
1352
|
setup Pick which endpoints agents can call, then get the aiReady() config to paste
|
|
1352
1353
|
inspect Show what agents see: every route, whether it's a tool, and why
|
|
1353
1354
|
describe Give tools real descriptions (AI-proposed and reviewed, or your own) in
|
|
1354
1355
|
${DESCRIPTIONS_FILE}, which aiReady() loads
|
|
1355
|
-
|
|
1356
|
+
${commands2.map(([name, help]) => name.length > 8 ? ` ${name}
|
|
1357
|
+
${help}
|
|
1358
|
+
` : ` ${name.padEnd(8)} ${help}
|
|
1359
|
+
`).join("")}${commands2.length ? ` (${bin} <command> --help for its options)
|
|
1360
|
+
` : ""}
|
|
1356
1361
|
Options:
|
|
1357
1362
|
--entry <path> ${entryHelp} (default: detected)
|
|
1358
1363
|
--env-vars <path> Load these variables into the scan (setup asks about .env otherwise)
|
|
@@ -1795,6 +1800,7 @@ ${bold("Step 3/5")} \xB7 Your aiReady() config${copyNote}
|
|
|
1795
1800
|
`);
|
|
1796
1801
|
console.log(code.replace(/^/gm, " "));
|
|
1797
1802
|
let applied = false;
|
|
1803
|
+
let manual = apply && "plan" in apply ? (apply.also ?? []).map((a) => a.manual) : [];
|
|
1798
1804
|
if (args.apply !== false && (args.apply || tty && !args.quick)) {
|
|
1799
1805
|
if (!apply) {
|
|
1800
1806
|
if (args.apply) console.log(yellow("\n Can't apply automatically here: paste it as described below."));
|
|
@@ -1803,20 +1809,31 @@ ${bold("Step 3/5")} \xB7 Your aiReady() config${copyNote}
|
|
|
1803
1809
|
Can't apply automatically: ${apply.blocked}. Paste it as described below.`));
|
|
1804
1810
|
} else {
|
|
1805
1811
|
const { summary } = apply.plan;
|
|
1812
|
+
const also = apply.also ?? [];
|
|
1813
|
+
const all = [summary, ...also.map((a) => a.plan.summary.replace(/^./, (c) => c.toLowerCase()))];
|
|
1806
1814
|
const yes = args.apply === true || ["y", "yes"].includes((await ask(`
|
|
1807
|
-
Apply this: ${
|
|
1815
|
+
Apply this: ${all.join(", and ")}? ${dim("(y/N)")} `)).toLowerCase());
|
|
1808
1816
|
if (yes) {
|
|
1809
1817
|
const written = writePlan(apply.plan);
|
|
1810
1818
|
if (written.ok) {
|
|
1811
1819
|
applied = true;
|
|
1812
1820
|
console.log(green(` \u2713 Applied: ${summary}.`) + dim(apply.plan.before === null ? "" : " Review it with git diff."));
|
|
1821
|
+
manual = [];
|
|
1822
|
+
for (const a of also) {
|
|
1823
|
+
const done = writePlan(a.plan);
|
|
1824
|
+
if (done.ok) console.log(green(` \u2713 Applied: ${a.plan.summary}.`) + dim(" Review it with git diff."));
|
|
1825
|
+
else {
|
|
1826
|
+
console.log(yellow(` Couldn't apply: ${a.plan.summary} (${done.error}).`));
|
|
1827
|
+
manual.push(a.manual);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1813
1830
|
} else console.log(yellow(` Couldn't apply: ${written.error}. Paste it as described below.`));
|
|
1814
1831
|
}
|
|
1815
1832
|
}
|
|
1816
1833
|
}
|
|
1817
1834
|
if (!applied) console.log(`
|
|
1818
1835
|
${hint.lines[0]}`);
|
|
1819
|
-
for (const line of hint.lines.slice(1)) console.log(` ${line}`);
|
|
1836
|
+
for (const line of [...hint.lines.slice(1), ...manual]) console.log(` ${line}`);
|
|
1820
1837
|
if (hint.warning) console.log(yellow(` ! ${hint.warning}`));
|
|
1821
1838
|
if (droppedGlobs.length > 0) {
|
|
1822
1839
|
console.log(yellow(` ! Dropped exclude ${droppedGlobs.map((g) => `"${g}"`).join(", ")}: it would hide endpoints you ticked.`));
|
|
@@ -2190,11 +2207,11 @@ async function runCli(argv, forAdapter, cwd = process.cwd()) {
|
|
|
2190
2207
|
args = parseArgs(argv);
|
|
2191
2208
|
} catch (err) {
|
|
2192
2209
|
console.error(red(err.message));
|
|
2193
|
-
console.error(usage(adapter
|
|
2210
|
+
console.error(usage(adapter));
|
|
2194
2211
|
return 2;
|
|
2195
2212
|
}
|
|
2196
2213
|
if (args.help || !args.command) {
|
|
2197
|
-
console.log(usage(adapter
|
|
2214
|
+
console.log(usage(adapter));
|
|
2198
2215
|
return args.help ? 0 : 2;
|
|
2199
2216
|
}
|
|
2200
2217
|
if (args.ci) disableColor();
|
|
@@ -2215,7 +2232,7 @@ async function runCli(argv, forAdapter, cwd = process.cwd()) {
|
|
|
2215
2232
|
if (args.command === "setup") return setup(args, cwd);
|
|
2216
2233
|
if (args.command === "describe") return describeCommand(args, cwd);
|
|
2217
2234
|
console.error(red(`unknown command: ${args.command}`));
|
|
2218
|
-
console.error(usage(adapter
|
|
2235
|
+
console.error(usage(adapter));
|
|
2219
2236
|
return 2;
|
|
2220
2237
|
}
|
|
2221
2238
|
export {
|