argsbarg 4.1.0 → 5.0.1
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/CHANGELOG.md +74 -1
- package/README.md +91 -85
- package/docs/README.md +8 -8
- package/docs/ai-skills.md +9 -9
- package/docs/bundled-docs.md +5 -5
- package/docs/cli-program.md +13 -11
- package/docs/config-schema.md +36 -9
- package/docs/configure.md +177 -0
- package/docs/developing.md +7 -7
- package/docs/distribution-homebrew.md +104 -0
- package/docs/mcp.md +11 -12
- package/docs/output-schema.md +1 -1
- package/examples/full-example/Formula/.gitkeep +0 -0
- package/examples/full-example/README.md +98 -0
- package/examples/full-example/biome.json +22 -0
- package/examples/{consumer-app → full-example}/bun.lock +2 -0
- package/examples/full-example/justfile +134 -0
- package/examples/{consumer-app → full-example}/package.json +10 -3
- package/examples/{consumer-app → full-example}/schemas/generated/app-config.json +1 -1
- package/examples/{consumer-app → full-example}/schemas/generated/status.json +1 -1
- package/examples/full-example/scripts/create-identity.ts +11 -0
- package/examples/full-example/scripts/formula-shared.ts +73 -0
- package/examples/full-example/scripts/gen-dev-formula.ts +26 -0
- package/examples/full-example/scripts/print-identity.ts +27 -0
- package/examples/full-example/src/commands/echo/command.ts +21 -0
- package/examples/full-example/src/commands/status/command.test.ts +10 -0
- package/examples/full-example/src/commands/status/command.ts +36 -0
- package/examples/{consumer-app → full-example}/src/commands/status/types.ts +1 -1
- package/examples/full-example/src/index.ts +10 -0
- package/examples/full-example/src/program.ts +57 -0
- package/examples/{consumer-app → full-example}/src/types.ts +1 -1
- package/examples/nested.ts +1 -3
- package/index.d.ts +49 -81
- package/package.json +2 -2
- package/src/builtins/builtins.test.ts +84 -64
- package/src/builtins/completion-group.ts +17 -17
- package/src/builtins/configure-copy.ts +86 -0
- package/src/builtins/configure.ts +70 -0
- package/src/builtins/dispatch.ts +13 -9
- package/src/builtins/index.ts +1 -1
- package/src/builtins/mcp.ts +2 -2
- package/src/builtins/registry.ts +6 -4
- package/src/capabilities.ts +22 -15
- package/src/cli-tool/cli-smoke.test.ts +29 -0
- package/src/cli-tool/create.test.ts +141 -0
- package/src/cli-tool/create.ts +402 -0
- package/{examples/consumer-app/capabilities.test.ts → src/cli-tool/full-example-capabilities.test.ts} +16 -15
- package/src/cli-tool/main.ts +8 -0
- package/src/cli-tool/post-create.ts +111 -0
- package/src/cli-tool/program.ts +97 -0
- package/src/cli-tool/prompt.ts +28 -0
- package/src/cli-tool/run-create.ts +138 -0
- package/src/cli.ts +0 -2
- package/src/config/bootstrap.ts +27 -18
- package/src/config/file.test.ts +1 -1
- package/src/config/resolve.test.ts +167 -0
- package/src/config/resolve.ts +52 -8
- package/src/configure/configure.test.ts +148 -0
- package/src/configure/index.ts +284 -0
- package/src/configure/prompt.ts +40 -0
- package/src/docs/api-guide.test.ts +4 -5
- package/src/docs/builtin.ts +3 -5
- package/src/docs/docs.test.ts +6 -5
- package/src/docs/mcp-guide.ts +11 -12
- package/src/index.ts +5 -12
- package/src/install/binary-placement.test.ts +101 -0
- package/src/install/binary-placement.ts +47 -0
- package/src/install/install-validate.test.ts +5 -5
- package/src/install/normalize-uninstall.ts +11 -0
- package/src/install/normalize.ts +4 -19
- package/src/install/opts.ts +17 -0
- package/src/install/paths.ts +0 -22
- package/src/install/plan.ts +14 -6
- package/src/install/shell.ts +0 -14
- package/src/install/status.test.ts +6 -6
- package/src/install/status.ts +0 -6
- package/src/install/target-effective.ts +8 -10
- package/src/install/target-scope.ts +26 -36
- package/src/install/target-types.ts +0 -16
- package/src/install/targets/app.ts +19 -28
- package/src/install/targets/configure.ts +6 -2
- package/src/install/targets/index.ts +0 -3
- package/src/install/targets.test.ts +26 -44
- package/src/invoke.test.ts +1 -1
- package/src/mcp/env.test.ts +92 -0
- package/src/mcp/env.ts +15 -14
- package/src/mcp/tools.ts +1 -1
- package/src/mcp.integration.test.ts +4 -4
- package/src/parse.test.ts +13 -14
- package/src/prompt.ts +10 -0
- package/src/schema.ts +1 -1
- package/src/skill/hint.ts +2 -2
- package/src/types.ts +48 -22
- package/src/validate.ts +22 -28
- package/docs/install.md +0 -290
- package/docs/templates/cursor/rules/cli-program.mdc +0 -31
- package/examples/config-app/main.ts +0 -20
- package/examples/config-app/program.ts +0 -78
- package/examples/config-app/schema.ts +0 -37
- package/examples/config-app/types.ts +0 -19
- package/examples/consumer-app/README.md +0 -56
- package/examples/consumer-app/src/main.ts +0 -15
- package/examples/consumer-app/src/program.ts +0 -108
- package/src/builtins/install.ts +0 -136
- package/src/install/app.ts +0 -94
- package/src/install/bootstrap.ts +0 -22
- package/src/install/completions.ts +0 -56
- package/src/install/index.ts +0 -415
- package/src/install/install.test.ts +0 -333
- package/src/install/targets/completions.ts +0 -133
- package/src/install/update.test.ts +0 -123
- package/src/install/update.ts +0 -54
- /package/examples/{consumer-app → full-example}/schemas/configSchemas.ts +0 -0
- /package/examples/{consumer-app → full-example}/schemas/outputSchemas.ts +0 -0
- /package/examples/{consumer-app → full-example}/scripts/schemagen/discover-schema-roots.test.ts +0 -0
- /package/examples/{consumer-app → full-example}/scripts/schemagen/discover-schema-roots.ts +0 -0
- /package/examples/{consumer-app → full-example}/scripts/schemagen/naming.ts +0 -0
- /package/examples/{consumer-app → full-example}/scripts/schemagen.ts +0 -0
- /package/examples/{consumer-app → full-example}/tsconfig.json +0 -0
package/src/builtins/dispatch.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { capabilityDeniedMessage, resolveCapabilities } from "../capabilities.ts";
|
|
2
2
|
import { Cli } from "../cli.ts";
|
|
3
|
+
import { cliConfigure } from "../configure/index.ts";
|
|
3
4
|
import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
4
|
-
import { cliInstall } from "../install/index.ts";
|
|
5
5
|
import { runMcpBundle } from "../mcp/bundle.ts";
|
|
6
6
|
import type { ParseResult } from "../parse.ts";
|
|
7
7
|
import { ParseKind } from "../parse.ts";
|
|
@@ -12,7 +12,7 @@ import { completionFishScript } from "./completion-fish.ts";
|
|
|
12
12
|
import { cliBuiltinCompletionGroup as completionGroup } from "./completion-group.ts";
|
|
13
13
|
import { completionZshScript } from "./completion-zsh.ts";
|
|
14
14
|
import { cliBuiltinConfigGroupIfEnabled } from "./config.ts";
|
|
15
|
-
import {
|
|
15
|
+
import { cliBuiltinConfigureCommand } from "./configure.ts";
|
|
16
16
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
17
17
|
import { cliPresentationRoot } from "./presentation.ts";
|
|
18
18
|
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
@@ -44,6 +44,10 @@ export async function dispatchBuiltin(
|
|
|
44
44
|
const caps = resolveCapabilities(program);
|
|
45
45
|
|
|
46
46
|
if (pr.path[0] === "completion") {
|
|
47
|
+
if (!caps.completion) {
|
|
48
|
+
process.stderr.write(capabilityDeniedMessage("completion"));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
47
51
|
const schemaForCompletion = completionSchema(program, opts);
|
|
48
52
|
if (pr.path[1] === "bash") {
|
|
49
53
|
process.stdout.write(completionBashScript(schemaForCompletion));
|
|
@@ -92,16 +96,16 @@ export async function dispatchBuiltin(
|
|
|
92
96
|
process.exit(1);
|
|
93
97
|
}
|
|
94
98
|
|
|
95
|
-
if (pr.path[0] === "
|
|
96
|
-
if (!caps.
|
|
97
|
-
process.stderr.write(capabilityDeniedMessage("
|
|
99
|
+
if (pr.path[0] === "configure") {
|
|
100
|
+
if (!caps.configure) {
|
|
101
|
+
process.stderr.write(capabilityDeniedMessage("configure"));
|
|
98
102
|
process.exit(1);
|
|
99
103
|
}
|
|
100
104
|
if (pr.path.length !== 1) {
|
|
101
|
-
process.stderr.write(`Unknown subcommand:
|
|
105
|
+
process.stderr.write(`Unknown subcommand: configure ${pr.path.slice(1).join(" ")}\n`);
|
|
102
106
|
process.exit(1);
|
|
103
107
|
}
|
|
104
|
-
await
|
|
108
|
+
await cliConfigure(program, pr.opts);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
@@ -128,12 +132,12 @@ export function builtinInterceptRoot(
|
|
|
128
132
|
};
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
if (first === "
|
|
135
|
+
if (first === "configure" && caps.configure) {
|
|
132
136
|
return {
|
|
133
137
|
parseRoot: {
|
|
134
138
|
key: program.key,
|
|
135
139
|
description: program.description,
|
|
136
|
-
commands: [
|
|
140
|
+
commands: [cliBuiltinConfigureCommand(program)],
|
|
137
141
|
},
|
|
138
142
|
isLeafCompletionIntercept: false,
|
|
139
143
|
};
|
package/src/builtins/index.ts
CHANGED
|
@@ -2,9 +2,9 @@ export { completionBashScript } from "./completion-bash.ts";
|
|
|
2
2
|
export { completionFishScript } from "./completion-fish.ts";
|
|
3
3
|
export { cliBuiltinCompletionGroup } from "./completion-group.ts";
|
|
4
4
|
export { completionZshScript } from "./completion-zsh.ts";
|
|
5
|
+
export { cliBuiltinConfigureCommand, configureBuiltinOptions } from "./configure.ts";
|
|
5
6
|
export { builtinInterceptRoot, dispatchBuiltin } from "./dispatch.ts";
|
|
6
7
|
export { type CliSchemaExport, exportPresentationBuiltins } from "./export.ts";
|
|
7
|
-
export { cliBuiltinInstallCommand, installBuiltinOptions } from "./install.ts";
|
|
8
8
|
export { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
9
9
|
export {
|
|
10
10
|
cliParseRoot,
|
package/src/builtins/mcp.ts
CHANGED
|
@@ -12,8 +12,8 @@ export function cliBuiltinMcpCommand(program: CliProgram): CliRouter {
|
|
|
12
12
|
" args: mcp",
|
|
13
13
|
"",
|
|
14
14
|
];
|
|
15
|
-
if (caps.
|
|
16
|
-
lines.push("Or:", "", " {argsbarg:program}
|
|
15
|
+
if (caps.configure) {
|
|
16
|
+
lines.push("Or:", "", " {argsbarg:program} configure", "");
|
|
17
17
|
}
|
|
18
18
|
if (docsEnabled(program)) {
|
|
19
19
|
lines.push("Full setup guide: {argsbarg:program} docs mcp");
|
package/src/builtins/registry.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
|
3
3
|
import type { CliNode, CliProgram } from "../types.ts";
|
|
4
4
|
import { cliBuiltinCompletionGroup } from "./completion-group.ts";
|
|
5
5
|
import { cliBuiltinConfigGroupIfEnabled } from "./config.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { cliBuiltinConfigureCommand } from "./configure.ts";
|
|
7
7
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
8
8
|
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
9
9
|
|
|
@@ -26,10 +26,12 @@ function pushBuiltin(
|
|
|
26
26
|
/** Capability-gated built-in command nodes in stable order (parse, help, export). */
|
|
27
27
|
export function resolveBuiltins(program: CliProgram, caps: CliCapabilities): CliNode[] {
|
|
28
28
|
const builtins: CliNode[] = [];
|
|
29
|
-
|
|
29
|
+
if (caps.completion) {
|
|
30
|
+
pushBuiltin(builtins, program, (p) => cliBuiltinCompletionGroup(p));
|
|
31
|
+
}
|
|
30
32
|
pushBuiltin(builtins, program, () => cliBuiltinVersionCommand());
|
|
31
|
-
if (caps.
|
|
32
|
-
pushBuiltin(builtins, program, (p) =>
|
|
33
|
+
if (caps.configure) {
|
|
34
|
+
pushBuiltin(builtins, program, (p) => cliBuiltinConfigureCommand(p));
|
|
33
35
|
}
|
|
34
36
|
pushBuiltin(builtins, program, (p) => cliBuiltinDocsGroupIfEnabled(p) ?? null);
|
|
35
37
|
if (caps.mcp) {
|
package/src/capabilities.ts
CHANGED
|
@@ -8,32 +8,33 @@ import type { CliProgram } from "./types.ts";
|
|
|
8
8
|
|
|
9
9
|
/** Platform builtins derived from program config and runtime. */
|
|
10
10
|
export interface CliCapabilities {
|
|
11
|
-
completion:
|
|
11
|
+
completion: boolean;
|
|
12
12
|
mcp: boolean;
|
|
13
|
-
|
|
13
|
+
configure: boolean;
|
|
14
14
|
docs: boolean;
|
|
15
|
-
update: boolean;
|
|
16
15
|
configCommands: boolean;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
/** Resolves which capabilities are enabled for a program. */
|
|
20
19
|
export function resolveCapabilities(program: CliProgram): CliCapabilities {
|
|
21
|
-
const
|
|
20
|
+
const configure = program.configure?.enabled !== false;
|
|
22
21
|
return {
|
|
23
|
-
completion:
|
|
22
|
+
completion: program.completion?.enabled !== false,
|
|
24
23
|
mcp: program.mcpServer?.enabled === true,
|
|
25
|
-
|
|
24
|
+
configure,
|
|
26
25
|
docs: program.docs?.enabled === true,
|
|
27
|
-
update: install && typeof program.install?.updateGetLatest === "function",
|
|
28
26
|
configCommands: configCommandsEnabled(program),
|
|
29
27
|
};
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
/** Reserved top-level command names for the given capabilities. */
|
|
33
31
|
export function reservedCommandNames(caps: CliCapabilities): string[] {
|
|
34
|
-
const names = ["
|
|
35
|
-
if (caps.
|
|
36
|
-
names.
|
|
32
|
+
const names = ["version"];
|
|
33
|
+
if (caps.completion) {
|
|
34
|
+
names.unshift("completion");
|
|
35
|
+
}
|
|
36
|
+
if (caps.configure) {
|
|
37
|
+
names.push("configure");
|
|
37
38
|
}
|
|
38
39
|
if (caps.docs) {
|
|
39
40
|
names.push("docs");
|
|
@@ -59,15 +60,17 @@ export function skipsRequiredAppConfigExit(path: string[], caps: CliCapabilities
|
|
|
59
60
|
return false;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
export type CapabilityFeature = "mcp" | "
|
|
63
|
+
export type CapabilityFeature = "mcp" | "configure" | "docs" | "config" | "completion";
|
|
63
64
|
|
|
64
65
|
/** Stderr message when a disabled built-in is invoked from the CLI. */
|
|
65
66
|
export function capabilityDeniedMessage(feature: CapabilityFeature): string {
|
|
66
67
|
switch (feature) {
|
|
68
|
+
case "completion":
|
|
69
|
+
return "Shell completion is not available for this app.\n";
|
|
67
70
|
case "mcp":
|
|
68
71
|
return "MCP is not available for this app.\n";
|
|
69
|
-
case "
|
|
70
|
-
return "
|
|
72
|
+
case "configure":
|
|
73
|
+
return "Configure is not available for this app.\n";
|
|
71
74
|
case "docs":
|
|
72
75
|
return "Documentation commands are not available for this app.\n";
|
|
73
76
|
case "config":
|
|
@@ -81,12 +84,16 @@ export function assertBuiltinAllowed(argv: string[], caps: CliCapabilities): voi
|
|
|
81
84
|
return;
|
|
82
85
|
}
|
|
83
86
|
const first = argv[0];
|
|
87
|
+
if (first === "completion" && !caps.completion) {
|
|
88
|
+
process.stderr.write(capabilityDeniedMessage("completion"));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
84
91
|
if (first === "mcp" && !caps.mcp) {
|
|
85
92
|
process.stderr.write(capabilityDeniedMessage("mcp"));
|
|
86
93
|
process.exit(1);
|
|
87
94
|
}
|
|
88
|
-
if (first === "
|
|
89
|
-
process.stderr.write(capabilityDeniedMessage("
|
|
95
|
+
if (first === "configure" && !caps.configure) {
|
|
96
|
+
process.stderr.write(capabilityDeniedMessage("configure"));
|
|
90
97
|
process.exit(1);
|
|
91
98
|
}
|
|
92
99
|
if (first === "docs" && !caps.docs) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
const main = join(import.meta.dir, "main.ts");
|
|
6
|
+
|
|
7
|
+
describe("argsbarg cli-tool", () => {
|
|
8
|
+
test("version subcommand prints version", () => {
|
|
9
|
+
const proc = spawnSync("bun", [main, "version"], { encoding: "utf8" });
|
|
10
|
+
expect(proc.status).toBe(0);
|
|
11
|
+
expect(proc.stdout.trim().length).toBeGreaterThan(0);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("help lists create and version only (no install, completion, mcp)", () => {
|
|
15
|
+
const proc = spawnSync("bun", [main, "--help"], { encoding: "utf8" });
|
|
16
|
+
expect(proc.status).toBe(0);
|
|
17
|
+
expect(proc.stdout).toContain("create");
|
|
18
|
+
expect(proc.stdout).toContain("version");
|
|
19
|
+
expect(proc.stdout).not.toContain("configure");
|
|
20
|
+
expect(proc.stdout).not.toContain("completion");
|
|
21
|
+
expect(proc.stdout).not.toContain("mcp");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("completion subcommand is disabled", () => {
|
|
25
|
+
const proc = spawnSync("bun", [main, "completion", "bash"], { encoding: "utf8" });
|
|
26
|
+
expect(proc.status).toBe(1);
|
|
27
|
+
expect(proc.stderr).toContain("Shell completion is not available");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import {
|
|
6
|
+
applyCreate,
|
|
7
|
+
classNameFromKey,
|
|
8
|
+
diffCreate,
|
|
9
|
+
diffCreateDetails,
|
|
10
|
+
renderCreateTree,
|
|
11
|
+
resolveCreateOptions,
|
|
12
|
+
substituteTemplateContent,
|
|
13
|
+
} from "./create.ts";
|
|
14
|
+
|
|
15
|
+
describe("argsbarg create", () => {
|
|
16
|
+
test("substitutes {key} tokens", () => {
|
|
17
|
+
const out = substituteTemplateContent(
|
|
18
|
+
"key={key} class={className} env={envPrefix}_API_TOKEN tap={tap} org={tapOrg}",
|
|
19
|
+
{
|
|
20
|
+
key: "my-cli",
|
|
21
|
+
className: "MyCli",
|
|
22
|
+
tap: "org/my-cli",
|
|
23
|
+
homepage: "https://github.com/org/my-cli",
|
|
24
|
+
releaseRepo: "org/my-cli",
|
|
25
|
+
desc: "My CLI",
|
|
26
|
+
force: false,
|
|
27
|
+
dryRun: false,
|
|
28
|
+
check: false,
|
|
29
|
+
diff: false,
|
|
30
|
+
yes: false,
|
|
31
|
+
devTemplate: false,
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
expect(out).toContain("my-cli");
|
|
35
|
+
expect(out).toContain("MyCli");
|
|
36
|
+
expect(out).toContain("MY_CLI_API_TOKEN");
|
|
37
|
+
expect(out).toContain("org/my-cli");
|
|
38
|
+
expect(out).not.toContain("{key}");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("classNameFromKey", () => {
|
|
42
|
+
expect(classNameFromKey("sqsp-i18n")).toBe("SqspI18n");
|
|
43
|
+
expect(classNameFromKey("at1")).toBe("At1");
|
|
44
|
+
expect(classNameFromKey("1password")).toBe("App1password");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("resolveCreateOptions derives identity defaults from key", () => {
|
|
48
|
+
expect(resolveCreateOptions({ key: "1password", releaseRepo: "org/1password" }).className).toBe(
|
|
49
|
+
"App1password",
|
|
50
|
+
);
|
|
51
|
+
expect(
|
|
52
|
+
resolveCreateOptions({ key: "my-cli", className: "Custom", releaseRepo: "org/my-cli" })
|
|
53
|
+
.className,
|
|
54
|
+
).toBe("Custom");
|
|
55
|
+
const opts = resolveCreateOptions({ key: "at1", releaseRepo: "bdombro/at1" });
|
|
56
|
+
expect(opts.tap).toBe("bdombro/at1");
|
|
57
|
+
expect(opts.releaseRepo).toBe("bdombro/at1");
|
|
58
|
+
expect(opts.homepage).toBe("https://github.com/bdombro/at1");
|
|
59
|
+
expect(opts.desc).toBe("At1 CLI");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("resolveCreateOptions requires release repo", () => {
|
|
63
|
+
expect(() => resolveCreateOptions({ key: "at1" })).toThrow(/release repo/i);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("renderCreateTree includes justfile and create-identity", () => {
|
|
67
|
+
const tree = renderCreateTree({
|
|
68
|
+
key: "testapp",
|
|
69
|
+
className: "Testapp",
|
|
70
|
+
tap: "local/testapp",
|
|
71
|
+
homepage: "https://example.com",
|
|
72
|
+
releaseRepo: "example/testapp",
|
|
73
|
+
desc: "Test",
|
|
74
|
+
force: false,
|
|
75
|
+
dryRun: false,
|
|
76
|
+
check: false,
|
|
77
|
+
diff: false,
|
|
78
|
+
yes: false,
|
|
79
|
+
devTemplate: false,
|
|
80
|
+
});
|
|
81
|
+
expect(tree.has("justfile")).toBe(true);
|
|
82
|
+
expect(tree.has("biome.json")).toBe(true);
|
|
83
|
+
expect(tree.has(".cursor/rules/code.mdc")).toBe(true);
|
|
84
|
+
expect(tree.has("scripts/create-identity.ts")).toBe(true);
|
|
85
|
+
const identity = tree.get("scripts/create-identity.ts");
|
|
86
|
+
expect(identity).toContain('key: "testapp"');
|
|
87
|
+
const formula = tree.get("scripts/formula-shared.ts");
|
|
88
|
+
expect(formula).toContain("create-identity.ts");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("--check detects drift", () => {
|
|
92
|
+
const dir = mkdtempSync(join(tmpdir(), "argsbarg-create-"));
|
|
93
|
+
try {
|
|
94
|
+
applyCreate(dir, {
|
|
95
|
+
key: "testapp",
|
|
96
|
+
className: "Testapp",
|
|
97
|
+
tap: "local/testapp",
|
|
98
|
+
homepage: "https://example.com",
|
|
99
|
+
releaseRepo: "example/testapp",
|
|
100
|
+
desc: "Test",
|
|
101
|
+
force: true,
|
|
102
|
+
dryRun: false,
|
|
103
|
+
check: false,
|
|
104
|
+
diff: false,
|
|
105
|
+
yes: false,
|
|
106
|
+
devTemplate: false,
|
|
107
|
+
});
|
|
108
|
+
expect(diffCreate(dir, { key: "testapp", className: "Testapp" })).toEqual([]);
|
|
109
|
+
} finally {
|
|
110
|
+
rmSync(dir, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("--check infers options from create-identity.ts", () => {
|
|
115
|
+
const dir = mkdtempSync(join(tmpdir(), "argsbarg-create-"));
|
|
116
|
+
try {
|
|
117
|
+
applyCreate(dir, {
|
|
118
|
+
key: "testapp",
|
|
119
|
+
className: "Testapp",
|
|
120
|
+
tap: "local/testapp",
|
|
121
|
+
homepage: "https://example.com",
|
|
122
|
+
releaseRepo: "example/testapp",
|
|
123
|
+
desc: "Test",
|
|
124
|
+
force: true,
|
|
125
|
+
dryRun: false,
|
|
126
|
+
check: false,
|
|
127
|
+
diff: false,
|
|
128
|
+
yes: false,
|
|
129
|
+
devTemplate: false,
|
|
130
|
+
});
|
|
131
|
+
expect(diffCreate(dir, { check: true })).toEqual([]);
|
|
132
|
+
} finally {
|
|
133
|
+
rmSync(dir, { recursive: true, force: true });
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("--diff captures drift details", () => {
|
|
138
|
+
const drifts = diffCreateDetails("/nonexistent", { key: "x", releaseRepo: "org/x" });
|
|
139
|
+
expect(drifts.length).toBeGreaterThan(0);
|
|
140
|
+
});
|
|
141
|
+
});
|