@tscircuit/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/bun.lockb CHANGED
Binary file
package/dist/cli.js CHANGED
@@ -210,7 +210,7 @@ import {Command} from "commander";
210
210
  // package.json
211
211
  var package_default = {
212
212
  name: "@tscircuit/cli",
213
- version: "0.0.2",
213
+ version: "0.0.4",
214
214
  private: false,
215
215
  type: "module",
216
216
  description: "Command line tool for developing, publishing and installing tscircuit circuits",
@@ -225,7 +225,8 @@ var package_default = {
225
225
  },
226
226
  bin: {
227
227
  tscircuit: "./dist/cli.js",
228
- tsci: "./dist/cli.js"
228
+ tsci: "./dist/cli.js",
229
+ tsck: "./dist/cli.js"
229
230
  },
230
231
  keywords: [],
231
232
  author: "",
@@ -250,7 +251,7 @@ var package_default = {
250
251
  minimist: "^1.2.8",
251
252
  "node-persist": "^4.0.1",
252
253
  open: "^10.1.0",
253
- "perfect-cli": "1.0.12",
254
+ "perfect-cli": "1.0.13",
254
255
  prompts: "^2.4.2",
255
256
  react: "^18.2.0",
256
257
  zod: "latest"
@@ -273,7 +274,7 @@ var package_default = {
273
274
 
274
275
  // lib/cmd-fns/config-reveal-location.ts
275
276
  var configRevealLocation = async (ctx, args) => {
276
- console.log(`tsci config path: ${ctx.global_config.path}`);
277
+ console.log(`tsck config path: ${ctx.global_config.path}`);
277
278
  };
278
279
  // lib/cmd-fns/config-set-registry.ts
279
280
  import {z} from "zod";
@@ -619,7 +620,7 @@ var soupifyCmd = async (ctx, args) => {
619
620
  console.log(JSON.stringify(soup, null, 2));
620
621
  }
621
622
  };
622
- // lib/cmd-fns/dev.ts
623
+ // lib/cmd-fns/dev/index.ts
623
624
  import {z as z16} from "zod";
624
625
  import kleur4 from "kleur";
625
626
  import {join as joinPath} from "path";
@@ -844,7 +845,7 @@ var bundle_default = {
844
845
  "index.html": Buffer.from("PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9IlVURi04IiAvPgogICAgPCEtLSA8bGluayByZWw9Imljb24iIHR5cGU9ImltYWdlL3N2Zyt4bWwiIGhyZWY9Ii92aXRlLnN2ZyIgLz4gLS0+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICAgIDx0aXRsZT5bZGV2XSB0c2NpcmN1aXQ8L3RpdGxlPgogICAgPHNjcmlwdCB0eXBlPSJtb2R1bGUiIGNyb3Nzb3JpZ2luIHNyYz0iL3ByZXZpZXcvYXNzZXRzL2luZGV4LUNpRUdEejdkLmpzIj48L3NjcmlwdD4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgY3Jvc3NvcmlnaW4gaHJlZj0iL3ByZXZpZXcvYXNzZXRzL2luZGV4LUNNNkk3TGhOLmNzcyI+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPGRpdiBpZD0icm9vdCI+PC9kaXY+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==", "base64")
845
846
  };
846
847
 
847
- // lib/cmd-fns/dev.ts
848
+ // lib/cmd-fns/dev/index.ts
848
849
  import defaultAxios from "axios";
849
850
  import {readdirSync, readFileSync} from "fs";
850
851
  import EdgeRuntimePrimitives from "@edge-runtime/primitives";
@@ -981,9 +982,145 @@ var devCmd = async (ctx, args) => {
981
982
  }
982
983
  }
983
984
  };
985
+ // lib/cmd-fns/init.ts
986
+ import {z as z17} from "zod";
987
+ import {
988
+ readFileSync as readFileSync2,
989
+ writeFileSync as writeFileSync3,
990
+ existsSync,
991
+ mkdirSync as mkdirSync2,
992
+ appendFileSync
993
+ } from "fs";
994
+ import * as Path3 from "node:path";
995
+ import $2 from "dax-sh";
996
+ var initCmd = async (ctx, args) => {
997
+ const params = z17.object({
998
+ name: z17.string().optional(),
999
+ dir: z17.string().optional(),
1000
+ runtime: z17.enum(["bun", "node"]).optional()
1001
+ }).parse(args);
1002
+ if (params.name && !params.dir) {
1003
+ params.dir = `./${params.name.split("/").pop()}`;
1004
+ } else if (!params.dir) {
1005
+ params.dir = `.`;
1006
+ }
1007
+ let runtime = params.runtime;
1008
+ if (!runtime) {
1009
+ const bunExists = $2.commandExistsSync("bun");
1010
+ if (bunExists) {
1011
+ runtime = "bun";
1012
+ } else {
1013
+ runtime = "node";
1014
+ }
1015
+ }
1016
+ const pkm = runtime === "bun" ? "bun" : "npm";
1017
+ const runner = runtime === "bun" ? "bun" : "tsx";
1018
+ const packageJsonExists = existsSync(Path3.join(params.dir, "package.json"));
1019
+ const dirExists = existsSync(params.dir);
1020
+ if (!dirExists) {
1021
+ console.log(`Creating directory ${params.dir}`);
1022
+ mkdirSync2(params.dir, { recursive: true });
1023
+ }
1024
+ process.chdir(params.dir);
1025
+ if (!packageJsonExists) {
1026
+ console.log(`Initializing ${pkm} project...`);
1027
+ await $2`${pkm} init -y`;
1028
+ }
1029
+ if (runtime !== "bun") {
1030
+ console.log(`Setting up project for typescript...`);
1031
+ await $2`${pkm} add -D typescript tsx`;
1032
+ }
1033
+ console.log("Changing package name...");
1034
+ const packageJson = JSON.parse(readFileSync2("package.json", "utf-8"));
1035
+ packageJson.name = params.name;
1036
+ writeFileSync3("package.json", JSON.stringify(packageJson, null, 2));
1037
+ console.log(`Adding ".tscircuit" to .gitignore`);
1038
+ appendFileSync(".gitignore", "\n.tscircuit", {
1039
+ encoding: "utf-8",
1040
+ flag: "w+"
1041
+ });
1042
+ console.log("Creating lib and examples directories...");
1043
+ mkdirSync2("examples", { recursive: true });
1044
+ mkdirSync2("lib", { recursive: true });
1045
+ writeFileSync3(Path3.join("lib", "MyCircuit.tsx"), `
1046
+ export const MyCircuit = () => (
1047
+ <resistor
1048
+ resistance="10kohm"
1049
+ name="R1"
1050
+ footprint="0805"
1051
+ />
1052
+ )
1053
+ `.trim());
1054
+ writeFileSync3("index.ts", `export * from "./lib/MyCircuit"`);
1055
+ writeFileSync3(Path3.join("examples", "MyExample.tsx"), `
1056
+ import { MyCircuit } from "lib/MyCircuit"
1057
+
1058
+ export const MyExample = () => (
1059
+ <MyCircuit />
1060
+ )
1061
+ `.trim());
1062
+ writeFileSync3("README.md", `
1063
+ # ${params.name}
1064
+
1065
+ > This project was generated using [tsck](https://github.com/tscircuit/tscircuit)
1066
+
1067
+ To develop and view the examples, run \`tsck dev\` and open [http://localhost:3020](http://localhost:3020) in your browser.
1068
+
1069
+ ## Developing
1070
+
1071
+ You should install an editor like [VS Code](https://code.visualstudio.com/) with a typescript extension. Many web developers already have this.
1072
+
1073
+ Usually, you'll want to develop some named circuits inside of the \`lib\` directory,
1074
+ export them in the \`index.ts\` file, then show how to use them in the \`examples\` directory.
1075
+
1076
+ Any file in \`examples\` will be automatically loaded and appear in the browser preview when you run \`tsck dev\`. It auto-reloads when you make changes, no need to reload the page or re-run the command.
1077
+
1078
+ > [!TIP] Make sure to replace this README with some details about your project and how to use it.
1079
+
1080
+ ## Publishing
1081
+
1082
+ After you're satisfied with your project, publish it on the [tscircuit registry](https://registry.tscircuit.com) with \`tsck publish\`
1083
+
1084
+
1085
+
1086
+ `.trim());
1087
+ writeFileSync3("tsconfig.json", `
1088
+ {
1089
+ "compilerOptions": {
1090
+ // Enable latest features
1091
+ "lib": ["ESNext"],
1092
+ "target": "ESNext",
1093
+ "module": "ESNext",
1094
+ "moduleDetection": "force",
1095
+ "jsx": "react-jsx",
1096
+ "allowJs": true,
1097
+ "types": ["@tscircuit/react-fiber"],
1098
+ "baseUrl": ".",
1099
+
1100
+ // Bundler mode
1101
+ "moduleResolution": "bundler",
1102
+ "allowImportingTsExtensions": true,
1103
+ "verbatimModuleSyntax": true,
1104
+ "noEmit": true,
1105
+
1106
+ // Best practices
1107
+ "strict": true,
1108
+ "skipLibCheck": true,
1109
+ "noFallthroughCasesInSwitch": true,
1110
+
1111
+ // Some stricter flags (disabled by default)
1112
+ "noUnusedLocals": false,
1113
+ "noUnusedParameters": false,
1114
+ "noPropertyAccessFromIndexSignature": false
1115
+ }
1116
+ }
1117
+
1118
+ `.trim());
1119
+ console.log("Done! Run `tsck dev` to start developing!");
1120
+ };
984
1121
  // lib/get-program.ts
985
1122
  var getProgram = (ctx) => {
986
- const cmd = new Command("tsci");
1123
+ const cmd = new Command("tsck");
987
1124
  cmd.version(package_default.version);
988
1125
  const authCmd = cmd.command("auth");
989
1126
  authCmd.command("login").action((args) => authLogin(ctx, args));
@@ -1017,11 +1154,12 @@ var getProgram = (ctx) => {
1017
1154
  packageExamples.command("get").requiredOption("--package-example-id <package_example_id>").action((args) => packageExamplesGet(ctx, args));
1018
1155
  packageExamples.command("create").requiredOption("--package-name-with-version <package_name_with_version>").requiredOption("--file <file>").option("--export <export>", "Name of export to soupify").action((args) => packageExamplesCreate(ctx, args));
1019
1156
  cmd.command("publish").action((args) => publish(ctx, args));
1020
- cmd.command("version").action(() => console.log(`tsci v${package_default.version}`));
1157
+ cmd.command("version").action(() => console.log(`tsck v${package_default.version}`));
1021
1158
  cmd.command("login").action((args) => authLogin(ctx, args));
1022
1159
  cmd.command("logout").action((args) => authLogout(ctx, args));
1023
1160
  cmd.command("soupify").requiredOption("--file <file>", "Input example files").option("--export <export_name>", "Name of export to soupify, if not specified, soupify the default/only export").action((args) => soupifyCmd(ctx, args));
1024
1161
  cmd.command("dev").option("--cwd <cwd>", "Current working directory").option("--port <port>", "Port to run dev server on").action((args) => devCmd(ctx, args));
1162
+ cmd.command("init").option("--name <name>", "Name of the project").option("--runtime <runtime>", "Runtime to use (attempts to bun, otherwise node/tsx)").option("--dir <dir>", "Directory to initialize (defaults to ./<name> or . if name not provided)").action((args) => initCmd(ctx, args));
1025
1163
  cmd.command("add").action((args) => {
1026
1164
  });
1027
1165
  cmd.command("remove").action((args) => {
@@ -1246,6 +1384,7 @@ var interactForPackageName = async ({
1246
1384
  var PARAM_HANDLERS_BY_PARAM_NAME = {
1247
1385
  file: interactForLocalFile,
1248
1386
  cwd: interactForLocalDirectory,
1387
+ dir: interactForLocalDirectory,
1249
1388
  package_release_id: interactForPackageReleaseId,
1250
1389
  package_name: interactForPackageName,
1251
1390
  package_name_with_version: interactForPackageNameWithVersion,
@@ -1255,7 +1394,7 @@ var PARAM_HANDLERS_BY_PARAM_NAME = {
1255
1394
  // lib/util/create-context-and-run-program.ts
1256
1395
  var createContextAndRunProgram = async (process_args) => {
1257
1396
  const args = minimist(process_args);
1258
- const global_config = new Configstore("tsci");
1397
+ const global_config = new Configstore("tsck");
1259
1398
  const current_profile = args.profile ?? global_config.get("current_profile") ?? "default";
1260
1399
  const profile_config = {
1261
1400
  get: (key) => global_config.get(`profiles.${current_profile}.${key}`),
@@ -24,4 +24,5 @@ export { packageExamplesGet } from "./package-examples-get"
24
24
  export { packageExamplesCreate } from "./package-examples-create"
25
25
  export { publish } from "./publish"
26
26
  export { soupifyCmd as soupify } from "./soupify"
27
- export { devCmd as dev } from "./dev/dev"
27
+ export { devCmd as dev } from "./dev"
28
+ export { initCmd as init } from "./init"
@@ -0,0 +1,172 @@
1
+ import { AppContext } from "../util/app-context"
2
+ import { z } from "zod"
3
+ import {
4
+ readFileSync,
5
+ writeFileSync,
6
+ existsSync,
7
+ mkdirSync,
8
+ writeFile,
9
+ appendFileSync,
10
+ } from "fs"
11
+ import * as Path from "node:path"
12
+ import $ from "dax-sh"
13
+
14
+ export const initCmd = async (ctx: AppContext, args: any) => {
15
+ const params = z
16
+ .object({
17
+ name: z.string().optional(),
18
+ dir: z.string().optional(),
19
+ runtime: z.enum(["bun", "node"]).optional(),
20
+ })
21
+ .parse(args)
22
+
23
+ if (params.name && !params.dir) {
24
+ params.dir = `./${params.name.split("/").pop()}`
25
+ } else if (!params.dir) {
26
+ params.dir = `.`
27
+ }
28
+
29
+ let runtime = params.runtime
30
+ if (!runtime) {
31
+ const bunExists = $.commandExistsSync("bun")
32
+
33
+ if (bunExists) {
34
+ runtime = "bun"
35
+ } else {
36
+ runtime = "node"
37
+ }
38
+ }
39
+
40
+ const pkm = runtime === "bun" ? "bun" : "npm"
41
+ const runner = runtime === "bun" ? "bun" : "tsx"
42
+
43
+ const packageJsonExists = existsSync(Path.join(params.dir, "package.json"))
44
+ const dirExists = existsSync(params.dir)
45
+
46
+ if (!dirExists) {
47
+ console.log(`Creating directory ${params.dir}`)
48
+ mkdirSync(params.dir, { recursive: true })
49
+ }
50
+
51
+ process.chdir(params.dir)
52
+ if (!packageJsonExists) {
53
+ console.log(`Initializing ${pkm} project...`)
54
+ await $`${pkm} init -y`
55
+ }
56
+
57
+ if (runtime !== "bun") {
58
+ console.log(`Setting up project for typescript...`)
59
+ await $`${pkm} add -D typescript tsx`
60
+ }
61
+
62
+ console.log("Changing package name...")
63
+ // Change package.json "name" to params.name
64
+ const packageJson = JSON.parse(readFileSync("package.json", "utf-8"))
65
+ packageJson.name = params.name
66
+ writeFileSync("package.json", JSON.stringify(packageJson, null, 2))
67
+
68
+ console.log(`Adding ".tscircuit" to .gitignore`)
69
+ appendFileSync(".gitignore", "\n.tscircuit", {
70
+ encoding: "utf-8",
71
+ flag: "w+",
72
+ })
73
+
74
+ console.log("Creating lib and examples directories...")
75
+ mkdirSync("examples", { recursive: true })
76
+ mkdirSync("lib", { recursive: true })
77
+
78
+ writeFileSync(
79
+ Path.join("lib", "MyCircuit.tsx"),
80
+ `
81
+ export const MyCircuit = () => (
82
+ <resistor
83
+ resistance="10kohm"
84
+ name="R1"
85
+ footprint="0805"
86
+ />
87
+ )
88
+ `.trim()
89
+ )
90
+
91
+ writeFileSync("index.ts", `export * from "./lib/MyCircuit"`)
92
+
93
+ writeFileSync(
94
+ Path.join("examples", "MyExample.tsx"),
95
+ `
96
+ import { MyCircuit } from "lib/MyCircuit"
97
+
98
+ export const MyExample = () => (
99
+ <MyCircuit />
100
+ )
101
+ `.trim()
102
+ )
103
+
104
+ // Override the README file
105
+ writeFileSync(
106
+ "README.md",
107
+ `
108
+ # ${params.name}
109
+
110
+ > This project was generated using [tsck](https://github.com/tscircuit/tscircuit)
111
+
112
+ To develop and view the examples, run \`tsck dev\` and open [http://localhost:3020](http://localhost:3020) in your browser.
113
+
114
+ ## Developing
115
+
116
+ You should install an editor like [VS Code](https://code.visualstudio.com/) with a typescript extension. Many web developers already have this.
117
+
118
+ Usually, you'll want to develop some named circuits inside of the \`lib\` directory,
119
+ export them in the \`index.ts\` file, then show how to use them in the \`examples\` directory.
120
+
121
+ Any file in \`examples\` will be automatically loaded and appear in the browser preview when you run \`tsck dev\`. It auto-reloads when you make changes, no need to reload the page or re-run the command.
122
+
123
+ > [!TIP] Make sure to replace this README with some details about your project and how to use it.
124
+
125
+ ## Publishing
126
+
127
+ After you're satisfied with your project, publish it on the [tscircuit registry](https://registry.tscircuit.com) with \`tsck publish\`
128
+
129
+
130
+
131
+ `.trim()
132
+ )
133
+
134
+ // Open tsconfig.json and modify it to import the tscircuit types
135
+ writeFileSync(
136
+ "tsconfig.json",
137
+ `
138
+ {
139
+ "compilerOptions": {
140
+ // Enable latest features
141
+ "lib": ["ESNext"],
142
+ "target": "ESNext",
143
+ "module": "ESNext",
144
+ "moduleDetection": "force",
145
+ "jsx": "react-jsx",
146
+ "allowJs": true,
147
+ "types": ["@tscircuit/react-fiber"],
148
+ "baseUrl": ".",
149
+
150
+ // Bundler mode
151
+ "moduleResolution": "bundler",
152
+ "allowImportingTsExtensions": true,
153
+ "verbatimModuleSyntax": true,
154
+ "noEmit": true,
155
+
156
+ // Best practices
157
+ "strict": true,
158
+ "skipLibCheck": true,
159
+ "noFallthroughCasesInSwitch": true,
160
+
161
+ // Some stricter flags (disabled by default)
162
+ "noUnusedLocals": false,
163
+ "noUnusedParameters": false,
164
+ "noPropertyAccessFromIndexSignature": false
165
+ }
166
+ }
167
+
168
+ `.trim()
169
+ )
170
+
171
+ console.log("Done! Run `tsck dev` to start developing!")
172
+ }
@@ -183,6 +183,19 @@ export const getProgram = (ctx: AppContext) => {
183
183
  .option("--port <port>", "Port to run dev server on")
184
184
  .action((args) => CMDFN.dev(ctx, args))
185
185
 
186
+ cmd
187
+ .command("init")
188
+ .option("--name <name>", "Name of the project")
189
+ .option(
190
+ "--runtime <runtime>",
191
+ "Runtime to use (attempts to bun, otherwise node/tsx)"
192
+ )
193
+ .option(
194
+ "--dir <dir>",
195
+ "Directory to initialize (defaults to ./<name> or . if name not provided)"
196
+ )
197
+ .action((args) => CMDFN.init(ctx, args))
198
+
186
199
  cmd.command("add").action((args) => {})
187
200
  cmd.command("remove").action((args) => {})
188
201
  cmd.command("install").action((args) => {})
@@ -9,6 +9,7 @@ import { ParamHandler } from "./param-handler-type"
9
9
  export const PARAM_HANDLERS_BY_PARAM_NAME: Record<string, ParamHandler> = {
10
10
  file: interactForLocalFile,
11
11
  cwd: interactForLocalDirectory,
12
+ dir: interactForLocalDirectory,
12
13
  package_release_id: interactForPackageReleaseId,
13
14
  package_name: interactForPackageName,
14
15
  package_name_with_version: interactForPackageNameWithVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Command line tool for developing, publishing and installing tscircuit circuits",
@@ -41,7 +41,7 @@
41
41
  "minimist": "^1.2.8",
42
42
  "node-persist": "^4.0.1",
43
43
  "open": "^10.1.0",
44
- "perfect-cli": "1.0.12",
44
+ "perfect-cli": "1.0.13",
45
45
  "prompts": "^2.4.2",
46
46
  "react": "^18.2.0",
47
47
  "zod": "latest"
@@ -60,4 +60,4 @@
60
60
  "tsx": "^4.7.1",
61
61
  "typescript": "^5.3.3"
62
62
  }
63
- }
63
+ }
@@ -0,0 +1,9 @@
1
+ import { test, expect, describe } from "bun:test"
2
+ import { $ } from "bun"
3
+
4
+ test.skip("tsck init", async () => {
5
+ await $`rm -rf ./tests/example-init`
6
+ console.log(
7
+ await $`bun cli.ts init --name init-test --dir ./tests/example-init`.text()
8
+ )
9
+ })