@stackshift-ui/scripts 1.0.0

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/hook.js ADDED
@@ -0,0 +1,62 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const __dir = path.resolve(__dirname, "..");
5
+ const TEMPLATE_DIR = "scripts/templates/";
6
+
7
+ /**
8
+ * Gets actions based on the provided data.
9
+ * @param {InquirerDataType} data - Input data.
10
+ * @returns {import('plop').ActionType[]} Actions.
11
+ */
12
+ function getActions(data) {
13
+ const actions = [];
14
+ if (!fs.existsSync(path.resolve(__dir, `${data.pkgPath}/src/hooks`, "index.ts"))) {
15
+ actions.push({
16
+ type: "add",
17
+ path: `${data.pkgPath}/src/hooks/index.ts`,
18
+ template: '// hooks exports\nexport * from "./{{kebabCase name}}";',
19
+ });
20
+ } else {
21
+ actions.push({
22
+ type: "append",
23
+ pattern: /(?<insertion> hooks exports)/,
24
+ path: `${data.pkgPath}/src/hooks/index.ts`,
25
+ template: 'export * from "./{{kebabCase name}}";',
26
+ });
27
+ }
28
+
29
+ ["", ".test"].forEach(suffix => {
30
+ actions.push({
31
+ type: "add",
32
+ path: `${data.pkgPath}/src/hooks/{{kebabCase name}}${suffix}.ts`,
33
+ templateFile: `${TEMPLATE_DIR}hook${suffix}.hbs`,
34
+ });
35
+ });
36
+
37
+ return actions;
38
+ }
39
+
40
+ module.exports = {
41
+ description: "Add a new React hook.",
42
+ prompts: [
43
+ {
44
+ type: "list",
45
+ name: "pkgPath",
46
+ choices: ["lib", "packages", "packages/shared"],
47
+ default: "lib",
48
+ message: "Select the package",
49
+ },
50
+ {
51
+ type: "input",
52
+ name: "name",
53
+ message: "What is the name of the hook?",
54
+ },
55
+ {
56
+ type: "input",
57
+ name: "description",
58
+ message: "Describe your custom hook. (This will be added as js-doc comment.)",
59
+ },
60
+ ],
61
+ actions: data => (data ? getActions(data) : []),
62
+ };
package/lite.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+ const config = require("./rebrand.config.json");
6
+
7
+ const packageJson = require("../lib/package.json");
8
+
9
+ const ref = packageJson.name;
10
+ packageJson.peerDependencies.r18gs = `${packageJson.dependencies.r18gs.split(".")[0]}`;
11
+ delete packageJson.dependencies.r18gs;
12
+ if (Object.keys(packageJson.dependencies).length === 0) delete packageJson.dependencies;
13
+ packageJson.name = `${ref}-lite`;
14
+
15
+ fs.writeFileSync(
16
+ path.resolve(__dirname, "../lib/package.json"),
17
+ JSON.stringify(packageJson, null, 2),
18
+ );
19
+
20
+ const readMePath = path.resolve(__dirname, "../lib", "README.md");
21
+
22
+ let readMe = fs.readFileSync(readMePath, { encoding: "utf8" });
23
+ const tmp = "!---";
24
+ const { owner, repo } = config;
25
+ readMe = readMe.replace(new RegExp(`${owner}/${repo}`, "g"), tmp);
26
+ readMe = readMe.replace(new RegExp(ref, "g"), packageJson.name);
27
+ readMe = readMe.replace(new RegExp(tmp, "g"), `${owner}/${repo}`);
28
+ readMe = readMe.replace(/## Want Lite Version(.|\n|\r)*You need `r18gs` as a peer-dependency/m, "");
29
+ fs.writeFileSync(readMePath, readMe);
@@ -0,0 +1,95 @@
1
+ /**
2
+ * allow only patch changes from release branches.
3
+ * Major and minor changes allowed only from main branch.
4
+ * pre-release only from branch containing dev or alpha in the branchname
5
+ */
6
+
7
+ /** Let the following error be thrown by npm. There are situations where publish could have failed for different reasons. */
8
+ // throws an exception if process.env.oldv === process.env.v The library version is not up to date, error(" Not able to release to the same version.
9
+
10
+ const { execSync } = require("child_process");
11
+ const fs = require("fs");
12
+ const path = require("path");
13
+
14
+ const BRANCH = process.env.BRANCH;
15
+ const DEFAULT_BRANCH = process.env.DEFAULT_BRANCH;
16
+
17
+ const isLatestRelease = BRANCH === DEFAULT_BRANCH || BRANCH.includes("release-");
18
+ let tag = "latest";
19
+
20
+ const OLD_VERSION = require("../lib/package.json").version;
21
+ if (!isLatestRelease) {
22
+ /** pre-release branch name should be the tag name (e.g., beta, canery, etc.) or tag name followed by a '-' and version or other specifiers. e.g. beta-2.0 */
23
+ tag = BRANCH.split("-")[0];
24
+ try {
25
+ execSync(`pnpm changeset pre enter ${tag}`);
26
+ } catch (e) {
27
+ console.log({ e });
28
+ }
29
+ }
30
+ /** Apply changeset */
31
+ execSync("pnpm changeset version");
32
+
33
+ // exit pre mode -- to avoid collision with full releases
34
+ try {
35
+ execSync("pnpm changeset pre exit");
36
+ } catch {
37
+ // empty
38
+ }
39
+
40
+ /** not requiring as require is cached by npm/node */
41
+ const NEW_VERSION = JSON.parse(
42
+ fs.readFileSync(path.resolve(__dirname, "..", "lib", "package.json")),
43
+ ).version;
44
+
45
+ const [newMajor, newMinor] = NEW_VERSION.split(".");
46
+ const [oldMajor, oldMinor] = OLD_VERSION.split(".");
47
+
48
+ const isNotPatch = newMajor !== oldMajor || newMinor !== oldMinor;
49
+
50
+ const pushCmd = `git add . && git commit -m "Apply changesets and update CHANGELOG" && git push origin ${BRANCH}`;
51
+
52
+ if (isNotPatch && BRANCH === DEFAULT_BRANCH) {
53
+ try {
54
+ execSync(pushCmd);
55
+ } catch (e) {
56
+ console.log({ e });
57
+ }
58
+ require("./update-security-md")(`${newMajor}.${newMinor}`, `${oldMajor}.${oldMinor}`);
59
+ /** Create new release branch for every Major or Minor release */
60
+ const releaseBranch = `release-${newMajor}.${newMinor}`;
61
+ execSync(`git checkout -b ${releaseBranch} && git push origin ${releaseBranch}`);
62
+ } else if (isLatestRelease) {
63
+ /** New version must be valid SEMVER version. No pre-release (beta/alpha etc.) */
64
+ if (!/^\d+\.\d+.\d+$/.test(NEW_VERSION)) throw new Error("Invalid version");
65
+
66
+ if (isNotPatch)
67
+ throw new Error("Major or Minor changes can be published only from the default branch.");
68
+
69
+ // Push changes back to the repo
70
+ try {
71
+ execSync(pushCmd);
72
+ } catch (e) {
73
+ console.log({ e });
74
+ }
75
+ } else {
76
+ try {
77
+ execSync(pushCmd);
78
+ } catch (e) {
79
+ console.log({ e });
80
+ }
81
+ }
82
+
83
+ const { visibility } = JSON.parse(execSync("gh repo view --json visibility").toString());
84
+ const provenance = visibility.toLowerCase() === "public" ? "--provenance" : "";
85
+
86
+ /** Create release */
87
+ execSync(`cd lib && pnpm build && npm publish ${provenance} --access public --tag ${tag}`);
88
+
89
+ /** Create GitHub release */
90
+ execSync(
91
+ `gh release create ${NEW_VERSION} --generate-notes${isLatestRelease ? " --latest" : ""} -n "$(sed '1,/^## /d;/^## /,$d' CHANGELOG.md)" --title "Release v${NEW_VERSION}"`,
92
+ );
93
+
94
+ // execSync("node ./scripts/lite.js");
95
+ // execSync(`cd lib && pnpm build && npm publish ${provenance} --access public --tag ${tag}`);
package/package.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@stackshift-ui/scripts",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "rebrand.js",
6
+ "scripts": {}
7
+ }
package/publish.js ADDED
@@ -0,0 +1,54 @@
1
+ /** It is assumed that this is called only from the default branch. */
2
+ const { execSync } = require("child_process");
3
+
4
+ // Apply changesets if any -- e.g., coming from pre-release branches
5
+ try {
6
+ execSync("pnpm changeset pre exit");
7
+ } catch {
8
+ // empty
9
+ }
10
+ try {
11
+ execSync("pnpm changeset version");
12
+ execSync(
13
+ `git add . && git commit -m "Apply changesets and update CHANGELOG" && git push origin main`,
14
+ );
15
+ } catch {
16
+ // no changesets to be applied
17
+ }
18
+
19
+ const { version: VERSION, name } = require("../packages/core/react/package.json");
20
+ let LATEST_VERSION = "0.0.-1";
21
+
22
+ try {
23
+ LATEST_VERSION = execSync(`npm view ${name} version`).toString().trim() ?? "0.0.1";
24
+ } catch {
25
+ // empty
26
+ }
27
+
28
+ console.log({ VERSION, LATEST_VERSION });
29
+
30
+ const [newMajor, newMinor] = VERSION.split(".");
31
+ const [oldMajor, oldMinor] = LATEST_VERSION.split(".");
32
+
33
+ const isPatch = newMajor === oldMajor && newMinor === oldMinor;
34
+
35
+ if (!isPatch) {
36
+ require("./update-security-md")(`${newMajor}.${newMinor}`, `${oldMajor}.${oldMinor}`);
37
+ /** Create new release branch for every Major or Minor release */
38
+ const releaseBranch = `release-${newMajor}.${newMinor}`;
39
+ execSync(`git checkout -b ${releaseBranch} && git push origin ${releaseBranch}`);
40
+ }
41
+
42
+ const { visibility } = JSON.parse(execSync("gh repo view --json visibility").toString());
43
+ const provenance = visibility.toLowerCase() === "public" ? "--provenance" : "";
44
+
45
+ /** Create release */
46
+ execSync(`cd lib && pnpm build && npm publish ${provenance} --access public`);
47
+
48
+ /** Create GitHub release */
49
+ execSync(
50
+ `gh release create ${VERSION} --generate-notes --latest -n "$(sed '1,/^## /d;/^## /,$d' CHANGELOG.md)" --title "Release v${VERSION}"`,
51
+ );
52
+
53
+ execSync("node ./scripts/lite.js");
54
+ execSync(`cd lib && pnpm build && npm publish ${provenance} --access public`);
package/rc.js ADDED
@@ -0,0 +1,208 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const __dir = path.resolve(__dirname, "..");
5
+ const TEMPLATE_DIR = "scripts/templates/";
6
+
7
+ /**
8
+ * @typedef {Object} InquirerDataType
9
+ * @property {boolean} isClient - Indicates whether a client component should be created.
10
+ * @property {string} name - Component name along with the relative path from either the client or server directory.
11
+ * @property {string} pkgPath - Package path.
12
+ */
13
+
14
+ /**
15
+ * Updates index files if needed based on the provided parameters.
16
+ * @param {import('plop').ActionType} nestedRouteActions - Nested route actions.
17
+ * @param {string[]} rootSegments - Root segments.
18
+ * @param {string[]} currentDirSegments - Current directory segments.
19
+ * @param {boolean} isClient - Indicates whether it's a client component.
20
+ */
21
+ function updateIndexFilesIfNeeded(nestedRouteActions, rootSegments, currentDirSegments, isClient) {
22
+ const indexFilePath = path.resolve(__dir, ...rootSegments, ...currentDirSegments, "index.ts");
23
+ const root = rootSegments.join("/");
24
+ if (!fs.existsSync(indexFilePath)) {
25
+ const content =
26
+ `${isClient ? '"use client";\n' : ""}// ${currentDirSegments.join("/")}` +
27
+ " component exports\n";
28
+ nestedRouteActions.push({
29
+ type: "add",
30
+ path: `${root + currentDirSegments.join("/")}/index.ts`,
31
+ template: content,
32
+ });
33
+ const length = currentDirSegments.length;
34
+ nestedRouteActions.push({
35
+ type: "append",
36
+ pattern: /(?<insertion> component exports)/,
37
+ path: `${
38
+ root + (length === 1 ? "" : `${currentDirSegments.slice(0, length - 1).join("/")}/`)
39
+ }index.ts`,
40
+ template: `export * from "./${currentDirSegments[length - 1]}"`,
41
+ });
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Converts a string to kebab-case.
47
+ * @param {string} str - The input string.
48
+ * @returns {string} The string in kebab-case.
49
+ */
50
+ function toKebabCase(str) {
51
+ return str
52
+ .trim()
53
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
54
+ .toLowerCase()
55
+ .replace(/ +/g, "-");
56
+ }
57
+
58
+ /**
59
+ * createRootIndexAndDeclarations if not present.
60
+ * @param {InquirerDataType} data - Input data.
61
+ */
62
+ function createRootIndexAndDeclarations(data) {
63
+ const nestedRouteActions = [];
64
+ const { isClient } = data;
65
+ const srcDir = path.resolve(__dir, `${data.pkgPath}/src`);
66
+ const [banner, target] = isClient ? ['"use client";\n\n', "client"] : ["", "server"];
67
+ const root = `${data.pkgPath}/src/${target}/`;
68
+
69
+ /** Create index.ts in src directory if not present. */
70
+ if (!fs.existsSync(path.resolve(srcDir, "index.ts")))
71
+ nestedRouteActions.push({
72
+ type: "add",
73
+ path: `${data.pkgPath}/src/index.ts`,
74
+ template: `${banner}export * from "./${target}";\n`,
75
+ });
76
+
77
+ /** Create declaration if not present. */
78
+ if (!fs.existsSync(path.resolve(srcDir, "declaration.d.ts")))
79
+ nestedRouteActions.push({
80
+ type: "add",
81
+ path: `${data.pkgPath}/src/declaration.d.ts`,
82
+ template: 'declare module "*.module.css";\ndeclare module "*.module.scss";\n',
83
+ });
84
+
85
+ /** Create index.ts in src/client or src/server directory if not present. */
86
+ if (!fs.existsSync(path.resolve(__dir, root, "index.ts")))
87
+ nestedRouteActions.push({
88
+ type: "add",
89
+ path: `${root}index.ts`,
90
+ template: `${banner}/**\n * Server components and client components need to be exported from separate files as\n * directive on top of the file from which component is imported takes effect.\n * i.e., server component re-exported from file with "use client" will behave as client component\n */\n\n// ${target} component exports\n`,
91
+ });
92
+
93
+ return { nestedRouteActions, root, isClient };
94
+ }
95
+
96
+ /**
97
+ * Gets nested route actions based on the provided data.
98
+ * @param {InquirerDataType} data - Input data.
99
+ * @returns {Object} Nested route actions and parent directory.
100
+ */
101
+ function getNestedRouteActions(data) {
102
+ const name = data.name.replace(/\/+/g, "/").replace(/\/$/, "").trim();
103
+ const { nestedRouteActions, root, isClient } = createRootIndexAndDeclarations(data);
104
+
105
+ if (!name.includes("/")) return { nestedRouteActions, parentDir: root };
106
+
107
+ const lastSlashInd = name.lastIndexOf("/") || name.lastIndexOf("\\");
108
+ data.name = name.slice(lastSlashInd + 1);
109
+
110
+ const directories = toKebabCase(name.slice(0, lastSlashInd)).split(/\/|\\/);
111
+ const rootSegments = [...root.split(/\/|\\/)];
112
+
113
+ for (let i = 1; i <= directories.length; i++)
114
+ updateIndexFilesIfNeeded(nestedRouteActions, rootSegments, directories.slice(0, i), isClient);
115
+
116
+ return { nestedRouteActions, parentDir: `${root + directories.join("/")}/` };
117
+ }
118
+
119
+ /**
120
+ * Gets the index action based on the provided data and parent directory.
121
+ * @param {InquirerDataType} data - Input data.
122
+ * @param {string} parentDir - Parent directory.
123
+ * @returns {Object} Index action.
124
+ */
125
+ function getIndexAction(data, parentDir) {
126
+ const indFilePath = path.resolve(__dir, parentDir, toKebabCase(data.name), "index.ts");
127
+ if (fs.existsSync(indFilePath))
128
+ return {
129
+ type: "append",
130
+ pattern: /(?<insertion> component exports)/,
131
+ path: `${parentDir}{{kebabCase name}}/index.ts`,
132
+ template: 'export * from "./{{kebabCase name}}";',
133
+ };
134
+ return {
135
+ type: "add",
136
+ path: `${parentDir}{{kebabCase name}}/index.ts`,
137
+ template: `${data.isClient ? '"use client";\n\n' : ""}// component exports\nexport * from "./{{kebabCase name}}";\n`,
138
+ };
139
+ }
140
+
141
+ /**
142
+ * Gets actions based on the provided data.
143
+ * @param {InquirerDataType} data - Input data.
144
+ * @returns {Array} Actions.
145
+ */
146
+ function getActions(data) {
147
+ const { nestedRouteActions, parentDir } = getNestedRouteActions(data);
148
+
149
+ return nestedRouteActions.concat([
150
+ getIndexAction(data, parentDir),
151
+ {
152
+ type: "add",
153
+ path: `${parentDir}{{kebabCase name}}/{{kebabCase name}}.tsx`,
154
+ templateFile: `${TEMPLATE_DIR}component.hbs`,
155
+ },
156
+ {
157
+ type: "add",
158
+ path: `${parentDir}{{kebabCase name}}/{{kebabCase name}}.test.tsx`,
159
+ templateFile: `${TEMPLATE_DIR}component.test.hbs`,
160
+ },
161
+ {
162
+ type: "add",
163
+ path: `${parentDir}{{kebabCase name}}/{{kebabCase name}}.module.scss`,
164
+ templateFile: `${TEMPLATE_DIR}component.module.hbs`,
165
+ },
166
+ {
167
+ type: "append",
168
+ pattern: /(?<insertion> component exports)/,
169
+ path: `${parentDir}index.ts`,
170
+ template: 'export * from "./{{kebabCase name}}";',
171
+ },
172
+ ]);
173
+ }
174
+
175
+ /** Export rc generator */
176
+ module.exports = {
177
+ description: "Adds a new React component to the selected package.",
178
+ prompts: [
179
+ {
180
+ type: "list",
181
+ name: "pkgPath",
182
+ choices: [
183
+ "lib",
184
+ "packages/components/common",
185
+ "packages/components/sections",
186
+ "packages/shared",
187
+ ],
188
+ default: "packages/components/common",
189
+ message: "Select the package",
190
+ },
191
+ {
192
+ type: "input",
193
+ name: "name",
194
+ message: "What is the name of the component?",
195
+ },
196
+ {
197
+ type: "confirm",
198
+ name: "isClient",
199
+ message: 'Is this a client component? (Should we add "use client" directive?)',
200
+ },
201
+ {
202
+ type: "input",
203
+ name: "description",
204
+ message: "Describe your component. (This will be added as js-doc comment.)",
205
+ },
206
+ ],
207
+ actions: data => (data ? getActions(data) : []),
208
+ };
@@ -0,0 +1,6 @@
1
+ {
2
+ "packageName": "components-library",
3
+ "owner": "stackshift-ui",
4
+ "repo": "components-library",
5
+ "title": "StackShift UI"
6
+ }
package/rebrand.js ADDED
@@ -0,0 +1,145 @@
1
+ const fs = require("node:fs");
2
+ const path = require("node:path");
3
+ // skipcq: JS-0258
4
+ const { prompt } = require("enquirer");
5
+ const { execSync } = require("child_process");
6
+
7
+ const [owner, repo] = execSync(
8
+ 'git remote get-url --push origin | sed "s/https:\\/\\/github.com\\///" | sed "s/.git//"',
9
+ )
10
+ .toString()
11
+ .trim()
12
+ .split("/");
13
+
14
+ const packageName = repo;
15
+
16
+ /** avoiding IIFE as formettter keeps misformettting IIFEs */
17
+ const rebrandFn = async () => {
18
+ const { shouldRebrand } = await prompt({
19
+ type: "confirm",
20
+ name: "shouldRebrand",
21
+ message: "Do you want to rebrand this repo?",
22
+ initial: true,
23
+ });
24
+
25
+ if (!shouldRebrand) return;
26
+
27
+ // if .tkb is not moved - setup workflow was not triggered or could not create the required commit
28
+ if (fs.existsSync(path.resolve(process.cwd(), "scripts", ".tkb"))) {
29
+ `rm .tkb
30
+ mv ./scripts/.tkb ./.tkb
31
+ rm -rf ./docs`
32
+ .split("\n")
33
+ .forEach(cmd => execSync(cmd.trim()));
34
+ }
35
+
36
+ const { installExt, ...answers } = await prompt([
37
+ {
38
+ type: "input",
39
+ name: "packageName",
40
+ message: "What is the name of your library?",
41
+ initial: packageName,
42
+ },
43
+ {
44
+ type: "input",
45
+ name: "owner",
46
+ message:
47
+ "Who is the owner of this repo? (GitHub user or organization login, .e.g, mayank1513)",
48
+ initial: owner,
49
+ },
50
+ {
51
+ type: "input",
52
+ name: "repo",
53
+ message: "What is the name of your repository?",
54
+ initial: repo,
55
+ },
56
+ {
57
+ type: "input",
58
+ name: "title",
59
+ message: "What is the title of your project?",
60
+ initial: packageName
61
+ .split("-")
62
+ .map(w => w[0].toUpperCase() + w.slice(1))
63
+ .join(" "),
64
+ },
65
+ {
66
+ type: "confirm",
67
+ name: "installExt",
68
+ message: "Do you want to install the recommended VS Code extensions?",
69
+ initial: true,
70
+ },
71
+ ]);
72
+
73
+ if (installExt) {
74
+ console.log("\x1b[32m", "Installing recommended VS Code extensions...");
75
+ execSync("code --install-extension mayank1513.trello-kanban-task-board");
76
+ execSync("code --install-extension esbenp.prettier-vscode");
77
+ }
78
+
79
+ console.log("\x1b[32m", "Creating rebrand.config.json...");
80
+ fs.writeFileSync(
81
+ path.resolve(process.cwd(), "scripts", "rebrand.config.json"),
82
+ JSON.stringify(answers, null, 2),
83
+ );
84
+
85
+ console.log("\x1b[32m", "rebranding...");
86
+ execSync("node ./scripts/rebrander.js");
87
+
88
+ console.log("\x1b[32m", "...");
89
+ console.log("\x1b[32m", "...");
90
+ console.log("\x1b[32m", "...");
91
+ console.log("\x1b[32m", "Clean up repo by removing things that you don't need");
92
+
93
+ const { pkgs } = await prompt({
94
+ type: "multiselect",
95
+ name: "pkgs",
96
+ message: "Select the examples or packages to remove",
97
+ choices: [
98
+ {
99
+ name: "examples/express",
100
+ message:
101
+ "Express.js example at examples/express -- You might want to keep this for server or API related functionality provided by your app.",
102
+ },
103
+ { name: "examples/remix", message: "Remix example at examples/remix." },
104
+ {
105
+ name: "packages/logger",
106
+ message:
107
+ "Logger package at packages/logger. The express example uses logger - handle it if needed.",
108
+ },
109
+ {
110
+ name: "packages/jest-presets",
111
+ message:
112
+ "We use vitest. You can keep this in case you want to use Jest. Note that the express example and logger package are set up to use jest with this jest-presets.",
113
+ },
114
+ ],
115
+ });
116
+
117
+ pkgs.forEach(pkg => execSync(`rm -rf ${pkg}`));
118
+
119
+ console.log("\x1b[32m", "90% of rebranding completed!");
120
+ console.log("\x1b[36m%s", ".");
121
+ console.log("\x1b[36m%s", ".");
122
+ console.log(
123
+ "\x1b[36m",
124
+ "Please open TKB (Workspace) and clear the Kanban Board to complete setting up your repo.",
125
+ );
126
+ console.log("\x1b[36m", ".");
127
+ console.log(
128
+ "\x1b[35m",
129
+ "To open TKB (Workspace) click on the `TKB (Workspace)` button on the vscode taskbar or follow these steps.",
130
+ );
131
+ console.log("\x1b[36m", ".");
132
+ console.log("\x1b[36m", " 1. Press `Ctrl/command` + `Shift` + `P` to open the command palette.");
133
+ console.log(
134
+ "\x1b[36m",
135
+ " 2. Type 'TrelloKanban: Workspace' and hit Enter to open the TKB (Workspace).",
136
+ );
137
+ console.log("\x1b[36m", ".");
138
+ console.log("\x1b[36m", ".");
139
+ console.log(
140
+ "\x1b[33m",
141
+ "If you have any issues, please raise an issue at https://github.com/react18-tools/turborepo-template/issues",
142
+ );
143
+ };
144
+
145
+ rebrandFn();