@stacksjs/buddy 0.70.257 → 0.70.259
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.d.ts +11 -1
- package/dist/cli.js +5 -164
- package/dist/commands/about.js +1 -35
- package/dist/commands/add.js +1 -25
- package/dist/commands/ai-context.js +4 -27
- package/dist/commands/auth.js +1 -68
- package/dist/commands/build.js +1 -221
- package/dist/commands/cd.js +8 -39
- package/dist/commands/changelog.js +1 -32
- package/dist/commands/clean.js +1 -44
- package/dist/commands/cloud.js +2 -519
- package/dist/commands/commit.js +1 -16
- package/dist/commands/completion.js +6 -42
- package/dist/commands/config-migrate.js +6 -94
- package/dist/commands/configure.js +2 -45
- package/dist/commands/create.js +1 -162
- package/dist/commands/deploy.d.ts +10 -4
- package/dist/commands/deploy.js +13 -1664
- package/dist/commands/desktop-apple.js +12 -399
- package/dist/commands/dev.js +6 -1083
- package/dist/commands/dns.js +3 -103
- package/dist/commands/docs/buddy-commands.js +10 -132
- package/dist/commands/docs/buddy-commands.test.js +1 -38
- package/dist/commands/docs/framework-repo.js +1 -14
- package/dist/commands/docs/framework-repo.test.js +1 -68
- package/dist/commands/docs/generated-artifacts.js +3 -70
- package/dist/commands/docs/generated-artifacts.test.js +1 -19
- package/dist/commands/docs/links.js +2 -85
- package/dist/commands/docs/links.test.js +4 -66
- package/dist/commands/docs.js +1 -24
- package/dist/commands/doctor.js +2 -478
- package/dist/commands/domains.js +2 -152
- package/dist/commands/email.js +31 -503
- package/dist/commands/env.js +1 -312
- package/dist/commands/extension.js +1 -239
- package/dist/commands/features.js +9 -345
- package/dist/commands/fresh.js +1 -46
- package/dist/commands/generate.js +2 -152
- package/dist/commands/http.js +1 -33
- package/dist/commands/index.js +1 -57
- package/dist/commands/install.js +1 -22
- package/dist/commands/key.js +1 -23
- package/dist/commands/link.js +2 -147
- package/dist/commands/lint.js +2 -46
- package/dist/commands/list.js +1 -140
- package/dist/commands/mail.js +15 -1477
- package/dist/commands/maintenance.js +1 -141
- package/dist/commands/make.js +1 -392
- package/dist/commands/migrate-project.js +1 -49
- package/dist/commands/migrate.js +27 -625
- package/dist/commands/outdated.js +1 -19
- package/dist/commands/package.js +1 -17
- package/dist/commands/phone.js +17 -181
- package/dist/commands/ports.js +2 -118
- package/dist/commands/prepublish.js +1 -17
- package/dist/commands/projects.js +1 -29
- package/dist/commands/protocol/craft-evidence.js +4 -98
- package/dist/commands/protocol/craft-evidence.test.js +1 -20
- package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
- package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
- package/dist/commands/protocol/desktop-support.js +2 -32
- package/dist/commands/protocol/desktop-workflow.test.js +3 -35
- package/dist/commands/protocol/driver-registry.js +2 -71
- package/dist/commands/protocol/pantry-evidence.js +4 -144
- package/dist/commands/protocol/pantry-evidence.test.js +1 -29
- package/dist/commands/protocol/release-manifest.js +3 -102
- package/dist/commands/protocol/release-manifest.test.js +2 -34
- package/dist/commands/protocol/run-conformance.js +4 -346
- package/dist/commands/protocol/run-conformance.test.js +1 -52
- package/dist/commands/protocol/run-driver-contracts.js +4 -83
- package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
- package/dist/commands/protocol/source-manifest.js +3 -113
- package/dist/commands/protocol/sync-suite.js +3 -136
- package/dist/commands/protocol/sync-suite.test.js +1 -44
- package/dist/commands/protocol.js +1 -60
- package/dist/commands/publish.js +8 -500
- package/dist/commands/queue.js +1 -248
- package/dist/commands/release.js +1 -42
- package/dist/commands/route.js +1 -21
- package/dist/commands/run-tool.js +1 -9
- package/dist/commands/saas.js +1 -25
- package/dist/commands/schedule.js +1 -61
- package/dist/commands/search.js +1 -84
- package/dist/commands/seed.js +1 -47
- package/dist/commands/serve.js +1 -55
- package/dist/commands/setup-ai.js +2 -121
- package/dist/commands/setup.js +2 -305
- package/dist/commands/share.js +1 -214
- package/dist/commands/sms.js +32 -319
- package/dist/commands/stacks.js +1 -72
- package/dist/commands/telemetry.js +1 -74
- package/dist/commands/test.js +1 -130
- package/dist/commands/tinker.js +1 -37
- package/dist/commands/types.js +1 -18
- package/dist/commands/upgrade.js +1 -98
- package/dist/commands/user.js +3 -84
- package/dist/commands/version.js +1 -14
- package/dist/config.js +1 -231
- package/dist/custom-cli.js +1 -23
- package/dist/database-preflight.js +1 -88
- package/dist/global-options.js +1 -4
- package/dist/index.js +1 -1
- package/dist/lazy-commands.js +1 -241
- package/dist/migrators/index.js +2 -62
- package/dist/migrators/laravel/index.js +1 -148
- package/dist/migrators/laravel/migrations.js +4 -231
- package/dist/migrators/laravel/models.js +8 -111
- package/dist/migrators/rails/index.js +1 -11
- package/dist/production-server.js +1 -257
- package/dist/project-setup.js +1 -36
- package/dist/serve-entry.js +1 -5
- package/dist/version-info.js +1 -5
- package/package.json +54 -47
package/dist/commands/http.js
CHANGED
|
@@ -1,33 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { log } from "@stacksjs/cli";
|
|
3
|
-
import { config } from "@stacksjs/config";
|
|
4
|
-
import { HttxClient } from "@stacksjs/httx";
|
|
5
|
-
import { ExitCode } from "@stacksjs/types";
|
|
6
|
-
export function http(buddy) {
|
|
7
|
-
const descriptions = {
|
|
8
|
-
http: "Send an HTTP request to a domain",
|
|
9
|
-
project: "Target a specific project",
|
|
10
|
-
verbose: "Enable verbose output"
|
|
11
|
-
};
|
|
12
|
-
buddy.command("http [domain]", descriptions.http).option("-p, --project [project]", descriptions.project, { default: !1 }).option("-v, --verbose", descriptions.verbose, { default: !1 }).action(async (domain, options) => {
|
|
13
|
-
log.debug("Running `buddy http [domain]` ...", options);
|
|
14
|
-
const url = domain || config.app.url;
|
|
15
|
-
if (!url)
|
|
16
|
-
throw Error("No domain configured. Pass a domain or set config.app.url.");
|
|
17
|
-
const client = new HttxClient({ verbose: options.verbose });
|
|
18
|
-
log.info(`GET ${url}`);
|
|
19
|
-
(await client.request(url.startsWith("http") ? url : `https://${url}`, {
|
|
20
|
-
method: "GET"
|
|
21
|
-
})).match({
|
|
22
|
-
ok: (response) => {
|
|
23
|
-
log.info(`${response.status} ${response.statusText} (${response.timings.duration.toFixed(0)}ms)`);
|
|
24
|
-
console.log(typeof response.data === "string" ? response.data : JSON.stringify(response.data, null, 2));
|
|
25
|
-
process.exit(ExitCode.Success);
|
|
26
|
-
},
|
|
27
|
-
err: (error) => {
|
|
28
|
-
log.error(`Request failed: ${error.message}`);
|
|
29
|
-
process.exit(ExitCode.FatalError);
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
}
|
|
1
|
+
import process from"node:process";import{log}from"@stacksjs/cli";import{config}from"@stacksjs/config";import{HttxClient}from"@stacksjs/httx";import{ExitCode}from"@stacksjs/types";export function http(buddy){const descriptions={http:"Send an HTTP request to a domain",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("http [domain]",descriptions.http).option("-p, --project [project]",descriptions.project,{default:!1}).option("-v, --verbose",descriptions.verbose,{default:!1}).action(async(domain,options)=>{log.debug("Running `buddy http [domain]` ...",options);const url=domain||config.app.url;if(!url)throw Error("No domain configured. Pass a domain or set config.app.url.");const client=new HttxClient({verbose:options.verbose});log.info(`GET ${url}`);(await client.request(url.startsWith("http")?url:`https://${url}`,{method:"GET"})).match({ok:(response)=>{log.info(`${response.status} ${response.statusText} (${response.timings.duration.toFixed(0)}ms)`);console.log(typeof response.data==="string"?response.data:JSON.stringify(response.data,null,2));process.exit(ExitCode.Success)},err:(error)=>{log.error(`Request failed: ${error.message}`);process.exit(ExitCode.FatalError)}})})}
|
package/dist/commands/index.js
CHANGED
|
@@ -1,57 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from "./auth";
|
|
3
|
-
export * from "./build";
|
|
4
|
-
export * from "./cd";
|
|
5
|
-
export * from "./changelog";
|
|
6
|
-
export * from "./clean";
|
|
7
|
-
export * from "./cloud";
|
|
8
|
-
export * from "./commit";
|
|
9
|
-
export * from "./completion";
|
|
10
|
-
export * from "./config-migrate";
|
|
11
|
-
export * from "./configure";
|
|
12
|
-
export * from "./create";
|
|
13
|
-
export * from "./deploy";
|
|
14
|
-
export * from "./dev";
|
|
15
|
-
export * from "./dns";
|
|
16
|
-
export * from "./docs";
|
|
17
|
-
export * from "./doctor";
|
|
18
|
-
export * from "./domains";
|
|
19
|
-
export * from "./email";
|
|
20
|
-
export * from "./env";
|
|
21
|
-
export * from "./features";
|
|
22
|
-
export * from "./fresh";
|
|
23
|
-
export * from "./generate";
|
|
24
|
-
export * from "./http";
|
|
25
|
-
export * from "./install";
|
|
26
|
-
export * from "./key";
|
|
27
|
-
export * from "./lint";
|
|
28
|
-
export * from "./list";
|
|
29
|
-
export * from "./mail";
|
|
30
|
-
export * from "./make";
|
|
31
|
-
export * from "./migrate";
|
|
32
|
-
export * from "./migrate-project";
|
|
33
|
-
export * from "./outdated";
|
|
34
|
-
export * from "./phone";
|
|
35
|
-
export * from "./ports";
|
|
36
|
-
export * from "./link";
|
|
37
|
-
export * from "./user";
|
|
38
|
-
export * from "./prepublish";
|
|
39
|
-
export * from "./projects";
|
|
40
|
-
export * from "./protocol";
|
|
41
|
-
export * from "./publish";
|
|
42
|
-
export * from "./queue";
|
|
43
|
-
export * from "./release";
|
|
44
|
-
export * from "./route";
|
|
45
|
-
export * from "./saas";
|
|
46
|
-
export * from "./schedule";
|
|
47
|
-
export * from "./search";
|
|
48
|
-
export * from "./seed";
|
|
49
|
-
export * from "./serve";
|
|
50
|
-
export * from "./setup";
|
|
51
|
-
export * from "./sms";
|
|
52
|
-
export * from "./telemetry";
|
|
53
|
-
export * from "./test";
|
|
54
|
-
export * from "./tinker";
|
|
55
|
-
export * from "./types";
|
|
56
|
-
export * from "./upgrade";
|
|
57
|
-
export * from "./version";
|
|
1
|
+
export*from"./about";export*from"./auth";export*from"./build";export*from"./cd";export*from"./changelog";export*from"./clean";export*from"./cloud";export*from"./commit";export*from"./completion";export*from"./config-migrate";export*from"./configure";export*from"./create";export*from"./deploy";export*from"./dev";export*from"./dns";export*from"./docs";export*from"./doctor";export*from"./domains";export*from"./email";export*from"./env";export*from"./features";export*from"./fresh";export*from"./generate";export*from"./http";export*from"./install";export*from"./key";export*from"./lint";export*from"./list";export*from"./mail";export*from"./make";export*from"./migrate";export*from"./migrate-project";export*from"./outdated";export*from"./phone";export*from"./ports";export*from"./link";export*from"./user";export*from"./prepublish";export*from"./projects";export*from"./protocol";export*from"./publish";export*from"./queue";export*from"./release";export*from"./route";export*from"./saas";export*from"./schedule";export*from"./search";export*from"./seed";export*from"./serve";export*from"./setup";export*from"./sms";export*from"./telemetry";export*from"./test";export*from"./tinker";export*from"./types";export*from"./upgrade";export*from"./version";
|
package/dist/commands/install.js
CHANGED
|
@@ -1,22 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { log, onUnknownSubcommand, runCommand } from "@stacksjs/cli";
|
|
3
|
-
import { path as p } from "@stacksjs/path";
|
|
4
|
-
import { ExitCode } from "@stacksjs/types";
|
|
5
|
-
export function install(buddy) {
|
|
6
|
-
const descriptions = {
|
|
7
|
-
install: "Install your dependencies",
|
|
8
|
-
project: "Target a specific project",
|
|
9
|
-
verbose: "Enable verbose output"
|
|
10
|
-
};
|
|
11
|
-
buddy.command("install", descriptions.install).option("-p, --project [project]", descriptions.project, { default: !1 }).option("-v, --verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
12
|
-
log.debug("Running `buddy install` ...", options);
|
|
13
|
-
if ((await runCommand("bun install", {
|
|
14
|
-
...options,
|
|
15
|
-
cwd: p.projectPath()
|
|
16
|
-
})).isErr) {
|
|
17
|
-
log.error("bun install failed");
|
|
18
|
-
process.exit(ExitCode.FatalError);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
onUnknownSubcommand(buddy, "install");
|
|
22
|
-
}
|
|
1
|
+
import process from"node:process";import{log,onUnknownSubcommand,runCommand}from"@stacksjs/cli";import{path as p}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";export function install(buddy){const descriptions={install:"Install your dependencies",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("install",descriptions.install).option("-p, --project [project]",descriptions.project,{default:!1}).option("-v, --verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy install` ...",options);if((await runCommand("bun install",{...options,cwd:p.projectPath()})).isErr){log.error("bun install failed");process.exit(ExitCode.FatalError)}});onUnknownSubcommand(buddy,"install")}
|
package/dist/commands/key.js
CHANGED
|
@@ -1,23 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { runAction } from "@stacksjs/actions";
|
|
3
|
-
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
-
import { Action } from "@stacksjs/enums";
|
|
5
|
-
import { ExitCode } from "@stacksjs/types";
|
|
6
|
-
export function key(buddy) {
|
|
7
|
-
const descriptions = {
|
|
8
|
-
command: "Generate & set the application key.",
|
|
9
|
-
project: "Target a specific project",
|
|
10
|
-
verbose: "Enable verbose output"
|
|
11
|
-
};
|
|
12
|
-
buddy.command("key:generate", descriptions.command).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
13
|
-
log.debug("Running `buddy key:generate` ...", options);
|
|
14
|
-
await intro("buddy key:generate");
|
|
15
|
-
const result = await runAction(Action.KeyGenerate, options);
|
|
16
|
-
if (result.isErr) {
|
|
17
|
-
log.error("Failed to set random application key.", result.error);
|
|
18
|
-
process.exit(ExitCode.FatalError);
|
|
19
|
-
}
|
|
20
|
-
await outro("Random application key set.");
|
|
21
|
-
});
|
|
22
|
-
onUnknownSubcommand(buddy, "key");
|
|
23
|
-
}
|
|
1
|
+
import process from"node:process";import{runAction}from"@stacksjs/actions";import{intro,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{Action}from"@stacksjs/enums";import{ExitCode}from"@stacksjs/types";export function key(buddy){const descriptions={command:"Generate & set the application key.",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("key:generate",descriptions.command).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy key:generate` ...",options);await intro("buddy key:generate");const result=await runAction(Action.KeyGenerate,options);if(result.isErr){log.error("Failed to set random application key.",result.error);process.exit(ExitCode.FatalError)}await outro("Random application key set.")});onUnknownSubcommand(buddy,"key")}
|
package/dist/commands/link.js
CHANGED
|
@@ -1,147 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { join, resolve } from "node:path";
|
|
5
|
-
import process from "node:process";
|
|
6
|
-
import { italic, log } from "@stacksjs/cli";
|
|
7
|
-
import { ExitCode } from "@stacksjs/types";
|
|
8
|
-
function recordPath() {
|
|
9
|
-
return join(process.cwd(), "storage/framework/runtime/linked-core.json");
|
|
10
|
-
}
|
|
11
|
-
function readRecord() {
|
|
12
|
-
try {
|
|
13
|
-
return JSON.parse(fs.readFileSync(recordPath(), "utf-8"));
|
|
14
|
-
} catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function writeRecord(record) {
|
|
19
|
-
fs.mkdirSync(join(process.cwd(), "storage/framework/runtime"), { recursive: !0 });
|
|
20
|
-
fs.writeFileSync(recordPath(), `${JSON.stringify(record, null, 2)}
|
|
21
|
-
`);
|
|
22
|
-
}
|
|
23
|
-
function resolveFrameworkPath(explicit) {
|
|
24
|
-
const candidates = [
|
|
25
|
-
explicit,
|
|
26
|
-
process.env.STACKS_FRAMEWORK_PATH,
|
|
27
|
-
resolve(process.cwd(), "../stacks"),
|
|
28
|
-
join(homedir(), "Code/stacks")
|
|
29
|
-
].filter(Boolean);
|
|
30
|
-
for (const candidate of candidates) {
|
|
31
|
-
const full = resolve(candidate);
|
|
32
|
-
if (existsSync(join(full, "storage/framework/core")))
|
|
33
|
-
return full;
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
function corePackages(framework) {
|
|
38
|
-
const coreDir = join(framework, "storage/framework/core"), found = new Map;
|
|
39
|
-
for (const entry of readdirSync(coreDir, { withFileTypes: !0 })) {
|
|
40
|
-
if (!entry.isDirectory())
|
|
41
|
-
continue;
|
|
42
|
-
const dir = join(coreDir, entry.name), manifest = join(dir, "package.json");
|
|
43
|
-
if (!existsSync(manifest))
|
|
44
|
-
continue;
|
|
45
|
-
try {
|
|
46
|
-
const { name } = JSON.parse(fs.readFileSync(manifest, "utf-8"));
|
|
47
|
-
if (name?.startsWith("@stacksjs/"))
|
|
48
|
-
found.set(name, dir);
|
|
49
|
-
} catch {}
|
|
50
|
-
}
|
|
51
|
-
return found;
|
|
52
|
-
}
|
|
53
|
-
function normalize(name) {
|
|
54
|
-
return `@stacksjs/${name.replace(/^@stacksjs\//, "").replace(/^core\//, "")}`;
|
|
55
|
-
}
|
|
56
|
-
function isSymlink(path) {
|
|
57
|
-
try {
|
|
58
|
-
return lstatSync(path).isSymbolicLink();
|
|
59
|
-
} catch {
|
|
60
|
-
return !1;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
export function link(buddy) {
|
|
64
|
-
buddy.command("link:core [...packages]", "Point this app's @stacksjs/* at a local framework checkout").option("--path <path>", "Framework checkout to link against").option("--all", "Link every core package the app has installed", { default: !1 }).example("buddy link:core auth router").example("buddy link:core --all --path ../stacks").action(async (packages, options) => {
|
|
65
|
-
const framework = resolveFrameworkPath(options?.path);
|
|
66
|
-
if (!framework) {
|
|
67
|
-
log.error("No framework checkout found.");
|
|
68
|
-
log.info("Pass one with `--path <dir>` or set STACKS_FRAMEWORK_PATH.");
|
|
69
|
-
process.exit(ExitCode.FatalError);
|
|
70
|
-
}
|
|
71
|
-
const available = corePackages(framework), modulesDir = join(process.cwd(), "node_modules"), wanted = (packages?.length ?? 0) > 0 ? packages.map(normalize) : [...available.keys()].filter((name) => existsSync(join(modulesDir, name)) || options?.all);
|
|
72
|
-
if (wanted.length === 0) {
|
|
73
|
-
log.info("Nothing to link: no installed @stacksjs/* packages found in this project.");
|
|
74
|
-
await log.flush();
|
|
75
|
-
process.exit(ExitCode.Success);
|
|
76
|
-
}
|
|
77
|
-
const linked = [], unbuilt = [];
|
|
78
|
-
for (const name of wanted) {
|
|
79
|
-
const source = available.get(name);
|
|
80
|
-
if (!source) {
|
|
81
|
-
log.warn(`${name} is not in ${italic(framework)} \u2014 skipped.`);
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
const target = join(modulesDir, name);
|
|
85
|
-
if (isSymlink(target) && realpathSync(target) === realpathSync(source)) {
|
|
86
|
-
linked.push(name);
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
fs.rmSync(target, { recursive: !0, force: !0 });
|
|
90
|
-
fs.mkdirSync(join(target, ".."), { recursive: !0 });
|
|
91
|
-
fs.symlinkSync(source, target, "dir");
|
|
92
|
-
linked.push(name);
|
|
93
|
-
if (!existsSync(join(source, "dist")))
|
|
94
|
-
unbuilt.push(name);
|
|
95
|
-
}
|
|
96
|
-
writeRecord({ framework, packages: linked });
|
|
97
|
-
log.success(`Linked ${linked.length} package${linked.length === 1 ? "" : "s"} to ${italic(framework)}`);
|
|
98
|
-
if (unbuilt.length > 0) {
|
|
99
|
-
log.warn(`Not built yet: ${unbuilt.join(", ")}`);
|
|
100
|
-
log.info("An app imports the build output, so each linked package needs `bun build.ts` in its directory.");
|
|
101
|
-
}
|
|
102
|
-
log.info("Undo with `buddy unlink:core`.");
|
|
103
|
-
await log.flush();
|
|
104
|
-
process.exit(ExitCode.Success);
|
|
105
|
-
});
|
|
106
|
-
buddy.command("unlink:core [...packages]", "Go back to the installed @stacksjs/* packages").option("--all", "Unlink everything that was linked", { default: !1 }).example("buddy unlink:core").action(async (packages, _options) => {
|
|
107
|
-
const record = readRecord(), modulesDir = join(process.cwd(), "node_modules"), wanted = (packages?.length ?? 0) > 0 ? packages.map(normalize) : record?.packages ?? readdirSync(join(modulesDir, "@stacksjs"), { withFileTypes: !0 }).filter((entry) => entry.isSymbolicLink()).map((entry) => `@stacksjs/${entry.name}`);
|
|
108
|
-
let removed = 0;
|
|
109
|
-
const unlinked = new Set;
|
|
110
|
-
for (const name of wanted) {
|
|
111
|
-
const target = join(modulesDir, name);
|
|
112
|
-
if (!isSymlink(target))
|
|
113
|
-
continue;
|
|
114
|
-
fs.rmSync(target, { force: !0 });
|
|
115
|
-
unlinked.add(name);
|
|
116
|
-
removed++;
|
|
117
|
-
}
|
|
118
|
-
const survivors = (record?.packages ?? []).filter((name) => !unlinked.has(name));
|
|
119
|
-
if (survivors.length > 0)
|
|
120
|
-
writeRecord({ framework: record.framework, packages: survivors });
|
|
121
|
-
else
|
|
122
|
-
fs.rmSync(recordPath(), { force: !0 });
|
|
123
|
-
if (removed === 0) {
|
|
124
|
-
log.info("Nothing was linked.");
|
|
125
|
-
await log.flush();
|
|
126
|
-
process.exit(ExitCode.Success);
|
|
127
|
-
}
|
|
128
|
-
log.info(`Unlinked ${removed} package${removed === 1 ? "" : "s"}; reinstalling the published copies...`);
|
|
129
|
-
if (await Bun.spawn(["bun", "install", "--force"], { cwd: process.cwd(), stdout: "inherit", stderr: "inherit" }).exited !== 0) {
|
|
130
|
-
log.error("`bun install` failed. The links are gone; re-run the install once the failure is resolved.");
|
|
131
|
-
process.exit(ExitCode.FatalError);
|
|
132
|
-
}
|
|
133
|
-
for (const name of survivors) {
|
|
134
|
-
const source = join(record.framework, "storage/framework/core", name.replace("@stacksjs/", "")), target = join(modulesDir, name);
|
|
135
|
-
if (!existsSync(source))
|
|
136
|
-
continue;
|
|
137
|
-
fs.rmSync(target, { recursive: !0, force: !0 });
|
|
138
|
-
fs.symlinkSync(source, target, "dir");
|
|
139
|
-
}
|
|
140
|
-
if (survivors.length > 0)
|
|
141
|
-
log.success(`Unlinked ${removed}; ${survivors.length} package${survivors.length === 1 ? "" : "s"} still linked.`);
|
|
142
|
-
else
|
|
143
|
-
log.success("This project is back on the published packages.");
|
|
144
|
-
await log.flush();
|
|
145
|
-
process.exit(ExitCode.Success);
|
|
146
|
-
});
|
|
147
|
-
}
|
|
1
|
+
import{existsSync,lstatSync,readdirSync,realpathSync}from"node:fs";import fs from"node:fs";import{homedir}from"node:os";import{join,resolve}from"node:path";import process from"node:process";import{italic,log}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";function recordPath(){return join(process.cwd(),"storage/framework/runtime/linked-core.json")}function readRecord(){try{return JSON.parse(fs.readFileSync(recordPath(),"utf-8"))}catch{return null}}function writeRecord(record){fs.mkdirSync(join(process.cwd(),"storage/framework/runtime"),{recursive:!0});fs.writeFileSync(recordPath(),`${JSON.stringify(record,null,2)}
|
|
2
|
+
`)}function resolveFrameworkPath(explicit){const candidates=[explicit,process.env.STACKS_FRAMEWORK_PATH,resolve(process.cwd(),"../stacks"),join(homedir(),"Code/stacks")].filter(Boolean);for(const candidate of candidates){const full=resolve(candidate);if(existsSync(join(full,"storage/framework/core")))return full}return null}function corePackages(framework){const coreDir=join(framework,"storage/framework/core"),found=new Map;for(const entry of readdirSync(coreDir,{withFileTypes:!0})){if(!entry.isDirectory())continue;const dir=join(coreDir,entry.name),manifest=join(dir,"package.json");if(!existsSync(manifest))continue;try{const{name}=JSON.parse(fs.readFileSync(manifest,"utf-8"));if(name?.startsWith("@stacksjs/"))found.set(name,dir)}catch{}}return found}function normalize(name){return`@stacksjs/${name.replace(/^@stacksjs\//,"").replace(/^core\//,"")}`}function isSymlink(path){try{return lstatSync(path).isSymbolicLink()}catch{return!1}}export function link(buddy){buddy.command("link:core [...packages]","Point this app's @stacksjs/* at a local framework checkout").option("--path <path>","Framework checkout to link against").option("--all","Link every core package the app has installed",{default:!1}).example("buddy link:core auth router").example("buddy link:core --all --path ../stacks").action(async(packages,options)=>{const framework=resolveFrameworkPath(options?.path);if(!framework){log.error("No framework checkout found.");log.info("Pass one with `--path <dir>` or set STACKS_FRAMEWORK_PATH.");process.exit(ExitCode.FatalError)}const available=corePackages(framework),modulesDir=join(process.cwd(),"node_modules"),wanted=(packages?.length??0)>0?packages.map(normalize):[...available.keys()].filter((name)=>existsSync(join(modulesDir,name))||options?.all);if(wanted.length===0){log.info("Nothing to link: no installed @stacksjs/* packages found in this project.");await log.flush();process.exit(ExitCode.Success)}const linked=[],unbuilt=[];for(const name of wanted){const source=available.get(name);if(!source){log.warn(`${name} is not in ${italic(framework)} \u2014 skipped.`);continue}const target=join(modulesDir,name);if(isSymlink(target)&&realpathSync(target)===realpathSync(source)){linked.push(name);continue}fs.rmSync(target,{recursive:!0,force:!0});fs.mkdirSync(join(target,".."),{recursive:!0});fs.symlinkSync(source,target,"dir");linked.push(name);if(!existsSync(join(source,"dist")))unbuilt.push(name)}writeRecord({framework,packages:linked});log.success(`Linked ${linked.length} package${linked.length===1?"":"s"} to ${italic(framework)}`);if(unbuilt.length>0){log.warn(`Not built yet: ${unbuilt.join(", ")}`);log.info("An app imports the build output, so each linked package needs `bun build.ts` in its directory.")}log.info("Undo with `buddy unlink:core`.");await log.flush();process.exit(ExitCode.Success)});buddy.command("unlink:core [...packages]","Go back to the installed @stacksjs/* packages").option("--all","Unlink everything that was linked",{default:!1}).example("buddy unlink:core").action(async(packages,_options)=>{const record=readRecord(),modulesDir=join(process.cwd(),"node_modules"),wanted=(packages?.length??0)>0?packages.map(normalize):record?.packages??readdirSync(join(modulesDir,"@stacksjs"),{withFileTypes:!0}).filter((entry)=>entry.isSymbolicLink()).map((entry)=>`@stacksjs/${entry.name}`);let removed=0;const unlinked=new Set;for(const name of wanted){const target=join(modulesDir,name);if(!isSymlink(target))continue;fs.rmSync(target,{force:!0});unlinked.add(name);removed++}const survivors=(record?.packages??[]).filter((name)=>!unlinked.has(name));if(survivors.length>0)writeRecord({framework:record.framework,packages:survivors});else fs.rmSync(recordPath(),{force:!0});if(removed===0){log.info("Nothing was linked.");await log.flush();process.exit(ExitCode.Success)}log.info(`Unlinked ${removed} package${removed===1?"":"s"}; reinstalling the published copies...`);if(await Bun.spawn(["bun","install","--force"],{cwd:process.cwd(),stdout:"inherit",stderr:"inherit"}).exited!==0){log.error("`bun install` failed. The links are gone; re-run the install once the failure is resolved.");process.exit(ExitCode.FatalError)}for(const name of survivors){const source=join(record.framework,"storage/framework/core",name.replace("@stacksjs/","")),target=join(modulesDir,name);if(!existsSync(source))continue;fs.rmSync(target,{recursive:!0,force:!0});fs.symlinkSync(source,target,"dir")}if(survivors.length>0)log.success(`Unlinked ${removed}; ${survivors.length} package${survivors.length===1?"":"s"} still linked.`);else log.success("This project is back on the published packages.");await log.flush();process.exit(ExitCode.Success)})}
|
package/dist/commands/lint.js
CHANGED
|
@@ -1,46 +1,2 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
|
|
3
|
-
import { ExitCode } from "@stacksjs/types";
|
|
4
|
-
async function runStyleAction(entry, label, options) {
|
|
5
|
-
const actions = await import("@stacksjs/actions"), { ok } = await actions[entry](options);
|
|
6
|
-
if (!ok) {
|
|
7
|
-
log.error(`${label} reported failure`);
|
|
8
|
-
process.exit(ExitCode.FatalError);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export function lint(buddy) {
|
|
12
|
-
const descriptions = {
|
|
13
|
-
lint: "Automagically lints your project codebase",
|
|
14
|
-
lintFix: "Automagically fixes all lint errors",
|
|
15
|
-
format: "Format your project codebase",
|
|
16
|
-
formatCheck: "Check formatting without making changes",
|
|
17
|
-
project: "Target a specific project",
|
|
18
|
-
verbose: "Enable verbose output"
|
|
19
|
-
};
|
|
20
|
-
buddy.command("lint", descriptions.lint).option("-f, --fix", descriptions.lintFix, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
21
|
-
log.debug("Running `buddy lint` ...", options);
|
|
22
|
-
const startTime = await intro("buddy lint");
|
|
23
|
-
await runStyleAction(options.fix ? "lintFix" : "lintProject", "lint");
|
|
24
|
-
await outro("Linted your project", { startTime, useSeconds: !0 });
|
|
25
|
-
});
|
|
26
|
-
buddy.command("lint:fix", descriptions.lintFix).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
27
|
-
log.debug("Running `buddy lint:fix` ...", options);
|
|
28
|
-
const startTime = await intro("buddy lint:fix");
|
|
29
|
-
log.info("Fixing lint errors...");
|
|
30
|
-
await runStyleAction("lintFix", "lint:fix");
|
|
31
|
-
await outro("Fixed lint errors", { startTime, useSeconds: !0 });
|
|
32
|
-
});
|
|
33
|
-
buddy.command("format", descriptions.format).option("-w, --write", "Write changes to files", { default: !1 }).option("-c, --check", descriptions.formatCheck, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
34
|
-
log.debug("Running `buddy format` ...", options);
|
|
35
|
-
const startTime = await intro("buddy format");
|
|
36
|
-
await runStyleAction("formatProject", "format", options.check ? { check: !0 } : { write: !0 });
|
|
37
|
-
await outro("Formatted your project", { startTime, useSeconds: !0 });
|
|
38
|
-
});
|
|
39
|
-
buddy.command("format:check", descriptions.formatCheck).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
40
|
-
log.debug("Running `buddy format:check` ...", options);
|
|
41
|
-
const startTime = await intro("buddy format:check");
|
|
42
|
-
await runStyleAction("formatProject", "format:check", { check: !0 });
|
|
43
|
-
await outro("Format check complete", { startTime, useSeconds: !0 });
|
|
44
|
-
});
|
|
45
|
-
onUnknownSubcommand(buddy, "lint");
|
|
46
|
-
}
|
|
1
|
+
import process from"node:process";import{intro,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";async function runStyleAction(entry,label,options){const actions=await import("@stacksjs/actions"),{ok}=await actions[entry](options);if(!ok){log.error(`${label} reported failure`);process.exit(ExitCode.FatalError)}}async function runStxChecks(startTime){const{runStxLint}=await import("@stacksjs/actions"),report=await runStxLint(),out=[""];for(const r of report.results)if(r.status==="fail"){out.push(` FAIL ${r.label}`);out.push(` ${r.count} found, baseline ${r.baseline}${r.why?` (${r.why})`:""}`);for(const line of r.detail.slice(0,8))out.push(` ${line}`)}else if(r.status==="loosened")out.push(` DROP ${r.label}: ${r.count} < baseline ${r.baseline} \u2014 lower it in config/lint.ts`);else out.push(` ok ${r.label}${r.baseline>0?` (${r.count}, held)`:""}`);if(report.distMissing)out.push(""," note: no build output found \u2014 the dist checks did not run. Run `./buddy build` first.");if(report.loosened>0){out.push(""," Current counts, for config/lint.ts:");for(const[id,count]of Object.entries(report.counts).sort(([a],[b])=>a.localeCompare(b)))out.push(` '${id}': ${count},`)}console.log(out.join(`
|
|
2
|
+
`));if(report.failed>0){log.error(`${report.failed} stx check(s) failed.`);await outro("stx checks failed",{startTime,useSeconds:!0});process.exit(ExitCode.FatalError)}if(report.loosened>0){log.warn(`No regressions, but ${report.loosened} baseline(s) are now stale.`);await outro("stx baselines stale",{startTime,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro("All stx checks pass",{startTime,useSeconds:!0})}export function lint(buddy){const descriptions={lint:"Automagically lints your project codebase",lintFix:"Automagically fixes all lint errors",format:"Format your project codebase",formatCheck:"Check formatting without making changes",project:"Target a specific project",stx:"Run the stx conformance checks instead of code style",verbose:"Enable verbose output"};buddy.command("lint",descriptions.lint).option("-f, --fix",descriptions.lintFix,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--stx",descriptions.stx,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy lint` ...",options);const startTime=await intro("buddy lint");if(options.stx){await runStxChecks(startTime);return}await runStyleAction(options.fix?"lintFix":"lintProject","lint");await outro("Linted your project",{startTime,useSeconds:!0})});buddy.command("lint:fix",descriptions.lintFix).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy lint:fix` ...",options);const startTime=await intro("buddy lint:fix");log.info("Fixing lint errors...");await runStyleAction("lintFix","lint:fix");await outro("Fixed lint errors",{startTime,useSeconds:!0})});buddy.command("format",descriptions.format).option("-w, --write","Write changes to files",{default:!1}).option("-c, --check",descriptions.formatCheck,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy format` ...",options);const startTime=await intro("buddy format");await runStyleAction("formatProject","format",options.check?{check:!0}:{write:!0});await outro("Formatted your project",{startTime,useSeconds:!0})});buddy.command("format:check",descriptions.formatCheck).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy format:check` ...",options);const startTime=await intro("buddy format:check");await runStyleAction("formatProject","format:check",{check:!0});await outro("Format check complete",{startTime,useSeconds:!0})});onUnknownSubcommand(buddy,"lint")}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,140 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { log } from "@stacksjs/logging";
|
|
3
|
-
import { onUnknownSubcommand } from "@stacksjs/cli";
|
|
4
|
-
export function list(buddy) {
|
|
5
|
-
const descriptions = {
|
|
6
|
-
list: "List all available Buddy commands",
|
|
7
|
-
project: "Target a specific project",
|
|
8
|
-
verbose: "Enable verbose output",
|
|
9
|
-
filter: "Filter commands by name or group",
|
|
10
|
-
namespace: "Filter commands by namespace (e.g., make, env, db)",
|
|
11
|
-
grouped: "Group commands by category",
|
|
12
|
-
format: "Output format (text, json)",
|
|
13
|
-
json: "Output the complete command inventory as JSON"
|
|
14
|
-
};
|
|
15
|
-
buddy.command("list", descriptions.list).option("-p, --project [project]", descriptions.project, { default: !1 }).option("-f, --filter [filter]", descriptions.filter).option("-n, --namespace [namespace]", descriptions.namespace).option("-g, --grouped", descriptions.grouped, { default: !0 }).option("--format [format]", descriptions.format, { default: "text" }).option("-J, --json", descriptions.json, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy list").example("buddy list --filter=make").example("buddy list --namespace=make").example("buddy list --namespace=env").example("buddy list --no-grouped").example("buddy list --format=json").example("buddy list --json").action(async (options) => {
|
|
16
|
-
log.debug("Running `buddy list` ...", options);
|
|
17
|
-
const { bold, dim, green } = await import("@stacksjs/cli"), commands = buddy.commands || [];
|
|
18
|
-
let filteredCommands = commands;
|
|
19
|
-
if (options.filter) {
|
|
20
|
-
const filterStr = String(options.filter).toLowerCase();
|
|
21
|
-
filteredCommands = commands.filter((cmd) => {
|
|
22
|
-
const name = canonicalCommandName(cmd), desc = cmd.description || "";
|
|
23
|
-
return name.toLowerCase().includes(filterStr) || desc.toLowerCase().includes(filterStr);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
if (options.namespace) {
|
|
27
|
-
const namespaceStr = String(options.namespace).toLowerCase();
|
|
28
|
-
filteredCommands = filteredCommands.filter((cmd) => {
|
|
29
|
-
return (cmd.namespace || "").toLowerCase() === namespaceStr;
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
if (filteredCommands.length === 0) {
|
|
33
|
-
if (usesJsonOutput(options))
|
|
34
|
-
console.log(JSON.stringify({ commands: [], total: 0 }, null, 2));
|
|
35
|
-
else {
|
|
36
|
-
console.log(dim("No commands found"));
|
|
37
|
-
if (options.filter)
|
|
38
|
-
console.log(dim(`Try removing the filter: ${options.filter}`));
|
|
39
|
-
}
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (usesJsonOutput(options)) {
|
|
43
|
-
const jsonOutput = filteredCommands.map(commandInventoryEntry).sort((a, b) => a.name.localeCompare(b.name));
|
|
44
|
-
console.log(JSON.stringify({ commands: jsonOutput, total: jsonOutput.length }, null, 2));
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
if (options.grouped) {
|
|
48
|
-
const groups = new Map;
|
|
49
|
-
for (const cmd of filteredCommands) {
|
|
50
|
-
const name = canonicalCommandName(cmd);
|
|
51
|
-
if (!name)
|
|
52
|
-
continue;
|
|
53
|
-
let group = "General";
|
|
54
|
-
if (name.includes(":"))
|
|
55
|
-
group = name.split(":")[0] ?? "General";
|
|
56
|
-
else if (["dev", "build", "test", "lint"].includes(name))
|
|
57
|
-
group = "Development";
|
|
58
|
-
else if (["deploy", "release", "publish"].includes(name))
|
|
59
|
-
group = "Deployment";
|
|
60
|
-
else if (["migrate", "seed", "fresh"].includes(name))
|
|
61
|
-
group = "Database";
|
|
62
|
-
else if (["doctor", "about", "version"].includes(name))
|
|
63
|
-
group = "Info";
|
|
64
|
-
if (!groups.has(group))
|
|
65
|
-
groups.set(group, []);
|
|
66
|
-
groups.get(group).push(cmd);
|
|
67
|
-
}
|
|
68
|
-
console.log("");
|
|
69
|
-
console.log(bold(green("Available Commands:")));
|
|
70
|
-
console.log("");
|
|
71
|
-
const sortedGroups = Array.from(groups.entries()).sort((a, b) => {
|
|
72
|
-
const order = ["Development", "General", "Info"], aIndex = order.indexOf(a[0]), bIndex = order.indexOf(b[0]);
|
|
73
|
-
if (aIndex >= 0 && bIndex >= 0)
|
|
74
|
-
return aIndex - bIndex;
|
|
75
|
-
if (aIndex >= 0)
|
|
76
|
-
return -1;
|
|
77
|
-
if (bIndex >= 0)
|
|
78
|
-
return 1;
|
|
79
|
-
return a[0].localeCompare(b[0]);
|
|
80
|
-
});
|
|
81
|
-
for (const [group, cmds] of sortedGroups) {
|
|
82
|
-
console.log(bold(`${group}:`));
|
|
83
|
-
cmds.sort((a, b) => canonicalCommandName(a).localeCompare(canonicalCommandName(b)));
|
|
84
|
-
for (const cmd of cmds) {
|
|
85
|
-
const name = canonicalCommandName(cmd).padEnd(20), desc = cmd.description || "";
|
|
86
|
-
console.log(` ${green(name)} ${dim(desc)}`);
|
|
87
|
-
}
|
|
88
|
-
console.log("");
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
console.log("");
|
|
92
|
-
console.log(bold(green("Available Commands:")));
|
|
93
|
-
console.log("");
|
|
94
|
-
filteredCommands.sort((a, b) => canonicalCommandName(a).localeCompare(canonicalCommandName(b)));
|
|
95
|
-
for (const cmd of filteredCommands) {
|
|
96
|
-
const name = canonicalCommandName(cmd).padEnd(20), desc = cmd.description || "";
|
|
97
|
-
console.log(` ${green(name)} ${dim(desc)}`);
|
|
98
|
-
}
|
|
99
|
-
console.log("");
|
|
100
|
-
}
|
|
101
|
-
console.log(dim(`Total: ${filteredCommands.length} commands`));
|
|
102
|
-
console.log("");
|
|
103
|
-
});
|
|
104
|
-
onUnknownSubcommand(buddy, "list");
|
|
105
|
-
}
|
|
106
|
-
export function commandInventoryEntry(command) {
|
|
107
|
-
const entry = {
|
|
108
|
-
name: canonicalCommandName(command),
|
|
109
|
-
description: command.description,
|
|
110
|
-
aliases: [...command.aliasNames],
|
|
111
|
-
usage: command.usageLine,
|
|
112
|
-
arguments: command.args.map((argument) => ({
|
|
113
|
-
name: argument.value,
|
|
114
|
-
required: argument.required,
|
|
115
|
-
variadic: argument.variadic
|
|
116
|
-
})),
|
|
117
|
-
options: command.options.map((option) => ({
|
|
118
|
-
name: option.name,
|
|
119
|
-
flags: declaredOptionFlags(option.rawName),
|
|
120
|
-
description: option.description,
|
|
121
|
-
required: option.required === !0,
|
|
122
|
-
boolean: option.isBoolean === !0,
|
|
123
|
-
negated: option.negated,
|
|
124
|
-
...option.config.default === void 0 ? {} : { default: option.config.default }
|
|
125
|
-
})),
|
|
126
|
-
examples: command.examples.map((example) => typeof example === "string" ? example : example("buddy"))
|
|
127
|
-
};
|
|
128
|
-
if (command.namespace)
|
|
129
|
-
entry.namespace = command.namespace;
|
|
130
|
-
return entry;
|
|
131
|
-
}
|
|
132
|
-
function canonicalCommandName(command) {
|
|
133
|
-
return command.namespace ? `${command.namespace}:${command.name}` : command.name;
|
|
134
|
-
}
|
|
135
|
-
function declaredOptionFlags(rawName) {
|
|
136
|
-
return [...rawName.matchAll(/-{1,2}([\w-]+)/g)].map((match) => match[1]);
|
|
137
|
-
}
|
|
138
|
-
function usesJsonOutput(options) {
|
|
139
|
-
return options.json === !0 || options.format === "json";
|
|
140
|
-
}
|
|
1
|
+
import process from"node:process";import{log}from"@stacksjs/logging";import{onUnknownSubcommand}from"@stacksjs/cli";export function list(buddy){const descriptions={list:"List all available Buddy commands",project:"Target a specific project",verbose:"Enable verbose output",filter:"Filter commands by name or group",namespace:"Filter commands by namespace (e.g., make, env, db)",grouped:"Group commands by category",format:"Output format (text, json)",json:"Output the complete command inventory as JSON"};buddy.command("list",descriptions.list).option("-p, --project [project]",descriptions.project,{default:!1}).option("-f, --filter [filter]",descriptions.filter).option("-n, --namespace [namespace]",descriptions.namespace).option("-g, --grouped",descriptions.grouped,{default:!0}).option("--format [format]",descriptions.format,{default:"text"}).option("-J, --json",descriptions.json,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy list").example("buddy list --filter=make").example("buddy list --namespace=make").example("buddy list --namespace=env").example("buddy list --no-grouped").example("buddy list --format=json").example("buddy list --json").action(async(options)=>{log.debug("Running `buddy list` ...",options);const{bold,dim,green}=await import("@stacksjs/cli"),commands=buddy.commands||[];let filteredCommands=commands;if(options.filter){const filterStr=String(options.filter).toLowerCase();filteredCommands=commands.filter((cmd)=>{const name=canonicalCommandName(cmd),desc=cmd.description||"";return name.toLowerCase().includes(filterStr)||desc.toLowerCase().includes(filterStr)})}if(options.namespace){const namespaceStr=String(options.namespace).toLowerCase();filteredCommands=filteredCommands.filter((cmd)=>{return(cmd.namespace||"").toLowerCase()===namespaceStr})}if(filteredCommands.length===0){if(usesJsonOutput(options))console.log(JSON.stringify({commands:[],total:0},null,2));else{console.log(dim("No commands found"));if(options.filter)console.log(dim(`Try removing the filter: ${options.filter}`))}return}if(usesJsonOutput(options)){const jsonOutput=filteredCommands.map(commandInventoryEntry).sort((a,b)=>a.name.localeCompare(b.name));console.log(JSON.stringify({commands:jsonOutput,total:jsonOutput.length},null,2));return}if(options.grouped){const groups=new Map;for(const cmd of filteredCommands){const name=canonicalCommandName(cmd);if(!name)continue;let group="General";if(name.includes(":"))group=name.split(":")[0]??"General";else if(["dev","build","test","lint"].includes(name))group="Development";else if(["deploy","release","publish"].includes(name))group="Deployment";else if(["migrate","seed","fresh"].includes(name))group="Database";else if(["doctor","about","version"].includes(name))group="Info";if(!groups.has(group))groups.set(group,[]);groups.get(group).push(cmd)}console.log("");console.log(bold(green("Available Commands:")));console.log("");const sortedGroups=Array.from(groups.entries()).sort((a,b)=>{const order=["Development","General","Info"],aIndex=order.indexOf(a[0]),bIndex=order.indexOf(b[0]);if(aIndex>=0&&bIndex>=0)return aIndex-bIndex;if(aIndex>=0)return-1;if(bIndex>=0)return 1;return a[0].localeCompare(b[0])});for(const[group,cmds]of sortedGroups){console.log(bold(`${group}:`));cmds.sort((a,b)=>canonicalCommandName(a).localeCompare(canonicalCommandName(b)));for(const cmd of cmds){const name=canonicalCommandName(cmd).padEnd(20),desc=cmd.description||"";console.log(` ${green(name)} ${dim(desc)}`)}console.log("")}}else{console.log("");console.log(bold(green("Available Commands:")));console.log("");filteredCommands.sort((a,b)=>canonicalCommandName(a).localeCompare(canonicalCommandName(b)));for(const cmd of filteredCommands){const name=canonicalCommandName(cmd).padEnd(20),desc=cmd.description||"";console.log(` ${green(name)} ${dim(desc)}`)}console.log("")}console.log(dim(`Total: ${filteredCommands.length} commands`));console.log("")});onUnknownSubcommand(buddy,"list")}export function commandInventoryEntry(command){const entry={name:canonicalCommandName(command),description:command.description,aliases:[...command.aliasNames],usage:command.usageLine,arguments:command.args.map((argument)=>({name:argument.value,required:argument.required,variadic:argument.variadic})),options:command.options.map((option)=>({name:option.name,flags:declaredOptionFlags(option.rawName),description:option.description,required:option.required===!0,boolean:option.isBoolean===!0,negated:option.negated,...option.config.default===void 0?{}:{default:option.config.default}})),examples:command.examples.map((example)=>typeof example==="string"?example:example("buddy"))};if(command.namespace)entry.namespace=command.namespace;return entry}function canonicalCommandName(command){return command.namespace?`${command.namespace}:${command.name}`:command.name}function declaredOptionFlags(rawName){return[...rawName.matchAll(/-{1,2}([\w-]+)/g)].map((match)=>match[1])}function usesJsonOutput(options){return options.json===!0||options.format==="json"}
|