nibs-cli 4.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/LICENSE +21 -0
- package/README.md +355 -0
- package/dist/cli.js +76 -0
- package/dist/commands/build.js +17 -0
- package/dist/commands/dist/NAI-story-engine.naiscript +844 -0
- package/dist/commands/new.js +136 -0
- package/dist/commands/project.js +22 -0
- package/dist/commands/rollup-config.js +48 -0
- package/dist/commands/watch.js +30 -0
- package/dist/utils/fetch.js +28 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Charles Nicholson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# NovelAI Script Build System
|
|
2
|
+
|
|
3
|
+
A CLI tool for building NovelAI scripts from TypeScript files. This tool uses Rollup to bundle multiple TypeScript files into single scripts that can be copied and pasted into the NovelAI script editor.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Standalone CLI Tool**: Install globally and use anywhere
|
|
8
|
+
- **Modular Development**: Write scripts across multiple TypeScript files with imports/exports
|
|
9
|
+
- **Automatic Type Definitions**: Fetches the latest NovelAI API types automatically
|
|
10
|
+
- **Type Safety**: Full TypeScript support with IntelliSense and type checking
|
|
11
|
+
- **Watch Mode**: Automatic rebuilds when files change during development
|
|
12
|
+
- **Single File Output**: Each project bundles into one script with no external dependencies
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### Prerequisites
|
|
17
|
+
|
|
18
|
+
- [Node.js](https://nodejs.org/) (v18 or higher)
|
|
19
|
+
- npm (comes with Node.js)
|
|
20
|
+
|
|
21
|
+
### Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g nibs-cli
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Your First Build
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
nibs build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This builds the current project. Output appears in `dist/`.
|
|
34
|
+
|
|
35
|
+
## Project Structure
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
my-novelai-script/
|
|
39
|
+
├── src/ # Your TypeScript files
|
|
40
|
+
│ ├── index.ts # Main entry point
|
|
41
|
+
│ └── utils.ts # Utility modules
|
|
42
|
+
├── project.yaml # Project configuration
|
|
43
|
+
├── tsconfig.json # TypeScript configuration
|
|
44
|
+
├── dist/ # Build output (generated)
|
|
45
|
+
│ └── my-script.naiscript # Built script ready for NovelAI
|
|
46
|
+
├── external/ # Auto-downloaded type definitions
|
|
47
|
+
│ └── script-types.d.ts
|
|
48
|
+
└── package.json # Optional (for your own development dependencies such as prettier formatter)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Creating a New Project
|
|
52
|
+
|
|
53
|
+
### Quick Start (No Configuration)
|
|
54
|
+
|
|
55
|
+
1. Use the new command:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
nibs new my-script
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This will create a new project in `my-script/` directory with the basic structure.
|
|
62
|
+
|
|
63
|
+
2. Edit your TypeScript files:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Edit the main script file
|
|
67
|
+
my-script/src/index.ts
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
3. Build:
|
|
71
|
+
```bash
|
|
72
|
+
cd my-script
|
|
73
|
+
nibs build
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The build system will auto-discover all `.ts` files in the `src/` folder and bundle them.
|
|
77
|
+
|
|
78
|
+
### Configuration (project.yaml)
|
|
79
|
+
|
|
80
|
+
Bundling incorporates metadata from a `project.yaml` file in your project folder. This unified configuration matches the YAML frontmatter of `.naiscript` files:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
compatibilityVersion: naiscript-1.0
|
|
84
|
+
id: xxxxxxxx-4xxx-xxxx-xxxx-xxxxxxxxxxxxxxxx
|
|
85
|
+
name: my-awesome-script
|
|
86
|
+
version: 1.0.0
|
|
87
|
+
author: Your Name <your.email@example.com>
|
|
88
|
+
description: My amazing NovelAI script
|
|
89
|
+
memoryLimit: 8
|
|
90
|
+
createdAt: 1234567890123
|
|
91
|
+
updatedAt: 1234567894564
|
|
92
|
+
config:
|
|
93
|
+
- # Custom configuration items here
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Fields:**
|
|
97
|
+
|
|
98
|
+
- `compatibilityVersion` - NAIScript compatibility version (always "naiscript-1.0")
|
|
99
|
+
- `id` - Unique ID required to update your script. Don't change.
|
|
100
|
+
- `name` - Output filename (creates `dist/{kebab-name}.naiscript`)
|
|
101
|
+
- `version` - Script version (appears in header)
|
|
102
|
+
- `author` - Your name/email (appears in header)
|
|
103
|
+
- `description` - Script description (appears in header)
|
|
104
|
+
- `memoryLimit` - How many megabytes of in-browser local-storage memory your script can use for storage. Maximum 128.
|
|
105
|
+
- `createdAt` - Timestamp of when your script was created
|
|
106
|
+
- `updatedAt` - Timestamp of when script was updated. Automatically updated on builds
|
|
107
|
+
- `config` - Array of custom configuration items (replaces config.yaml)
|
|
108
|
+
|
|
109
|
+
## CLI Commands
|
|
110
|
+
|
|
111
|
+
| Command | Description |
|
|
112
|
+
|---------|-------------|
|
|
113
|
+
| `nibs new <directory>` | Create a new project |
|
|
114
|
+
| `nibs build [directory]` | Build project (default command) |
|
|
115
|
+
| `nibs watch [directory]` | Watch project and rebuild on changes |
|
|
116
|
+
| `nibs help` | Show help information |
|
|
117
|
+
|
|
118
|
+
## Writing Scripts with Imports
|
|
119
|
+
|
|
120
|
+
You can split your code across multiple files using imports/exports. The build system removes all module syntax in the final output.
|
|
121
|
+
|
|
122
|
+
### Named Imports (Traditional Style)
|
|
123
|
+
|
|
124
|
+
**src/utils.ts**
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
export interface Config {
|
|
128
|
+
enabled: boolean;
|
|
129
|
+
debugMode: boolean;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function saveConfig(config: Config) {
|
|
133
|
+
await api.v1.storage.set("config", config);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function log(message: string) {
|
|
137
|
+
api.v1.log(`[MyScript] ${message}`);
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**src/index.ts**
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import type { Config } from "./utils";
|
|
145
|
+
import { saveConfig, log } from "./utils";
|
|
146
|
+
|
|
147
|
+
const config: Config = {
|
|
148
|
+
enabled: true,
|
|
149
|
+
debugMode: false,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
async function init() {
|
|
153
|
+
log("Starting...");
|
|
154
|
+
await saveConfig(config);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
init();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Namespace Imports
|
|
161
|
+
|
|
162
|
+
You can also use namespace imports (`import * as name`) to keep track of where functions come from:
|
|
163
|
+
|
|
164
|
+
**src/index.ts**
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import type { Config } from "./utils";
|
|
168
|
+
import * as utils from "./utils";
|
|
169
|
+
|
|
170
|
+
const config: Config = {
|
|
171
|
+
enabled: true,
|
|
172
|
+
debugMode: false,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
async function init() {
|
|
176
|
+
utils.log("Starting...");
|
|
177
|
+
await utils.saveConfig(config);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
init();
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The build system automatically generates a namespace wrapper object using Rollup:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const utils = {
|
|
187
|
+
saveConfig,
|
|
188
|
+
log,
|
|
189
|
+
};
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
You can mix both styles in the same file if needed.
|
|
193
|
+
|
|
194
|
+
## NovelAI API Reference
|
|
195
|
+
|
|
196
|
+
The build system automatically downloads NovelAI type definitions. In supported editors you get full completion and IDE documentation.
|
|
197
|
+
|
|
198
|
+
**Official Documentation**: [NovelAI Scripting Docs](https://docs.novelai.net/scripting/introduction.html)
|
|
199
|
+
|
|
200
|
+
## Example Projects
|
|
201
|
+
|
|
202
|
+
Two example projects are included to demonstrate different use cases:
|
|
203
|
+
|
|
204
|
+
### example-script (Full-Featured)
|
|
205
|
+
|
|
206
|
+
Located in `examples/example-script/`, this demonstrates:
|
|
207
|
+
|
|
208
|
+
- **Modular code organization** with imports/exports across files
|
|
209
|
+
- **UI
|
|
210
|
+
extensions** - Toolbar buttons with callbacks
|
|
211
|
+
- **Generation hooks** - Intercept and modify generation
|
|
212
|
+
- **Persistent storage** - Track data across script loads
|
|
213
|
+
- **Lorebook API** - Query and filter entries
|
|
214
|
+
- **Type safety** - TypeScript interfaces
|
|
215
|
+
|
|
216
|
+
### word-counter (Simple)
|
|
217
|
+
|
|
218
|
+
Located in `examples/word-counter/`, this demonstrates:
|
|
219
|
+
|
|
220
|
+
- **Single-file script** - Simple project structure
|
|
221
|
+
- **Document API** - Reading story text
|
|
222
|
+
- **Editor API** - Getting text selection
|
|
223
|
+
- **UI toasts** - Displaying information to users
|
|
224
|
+
- **Toolbar buttons** - Adding custom UI
|
|
225
|
+
|
|
226
|
+
## Tips and Best Practices
|
|
227
|
+
|
|
228
|
+
### Use Watch Mode During Development
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
nibs watch
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Auto-rebuilds when you save. Keep it running while you work!
|
|
235
|
+
|
|
236
|
+
### Debugging
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// Use api.v1.log, not console.log
|
|
240
|
+
api.v1.log("Debug:", someVariable);
|
|
241
|
+
api.v1.error("Error:", error);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Output appears in browser console (F12).
|
|
245
|
+
|
|
246
|
+
### Code Organization
|
|
247
|
+
|
|
248
|
+
**Simple script:**
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
src/
|
|
252
|
+
└── index.ts
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Medium script:**
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
src/
|
|
259
|
+
├── utils.ts
|
|
260
|
+
└── index.ts
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Complex script:**
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
src/
|
|
267
|
+
├── types.ts
|
|
268
|
+
├── config.ts
|
|
269
|
+
├── storage.ts
|
|
270
|
+
├── hooks.ts
|
|
271
|
+
├── ui.ts
|
|
272
|
+
└── index.ts
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Troubleshooting
|
|
276
|
+
|
|
277
|
+
### "Cannot find module" errors
|
|
278
|
+
|
|
279
|
+
1. Run `npm install`
|
|
280
|
+
2. Restart your TypeScript language server
|
|
281
|
+
3. Run `nibs build` to download type definitions
|
|
282
|
+
|
|
283
|
+
### Type definitions not found
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
rm -rf external/
|
|
287
|
+
nibs build
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Script doesn't work in NovelAI
|
|
291
|
+
|
|
292
|
+
1. Check browser console (F12) for errors
|
|
293
|
+
2. Verify script is enabled in NovelAI
|
|
294
|
+
3. Check that your TypeScript files compile correctly
|
|
295
|
+
4. Verify that your scripts don't use unsupported browser APIs
|
|
296
|
+
|
|
297
|
+
### Build errors
|
|
298
|
+
|
|
299
|
+
1. Check for TypeScript syntax errors in your source files
|
|
300
|
+
2. Make sure all imported files exist and have correct extensions
|
|
301
|
+
3. Verify that you're using the latest version of the build system:
|
|
302
|
+
```bash
|
|
303
|
+
npm install -g nibs-cli
|
|
304
|
+
```
|
|
305
|
+
4. For Rollup-related issues, try a clean build:
|
|
306
|
+
```bash
|
|
307
|
+
rm -rf dist/
|
|
308
|
+
nibs build
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## FAQ
|
|
312
|
+
|
|
313
|
+
### Can I use npm packages?
|
|
314
|
+
|
|
315
|
+
No. NovelAI scripts run in the browser without npm access. Use only:
|
|
316
|
+
|
|
317
|
+
- Browser-native APIs
|
|
318
|
+
- The NovelAI API (`api.v1.*`)
|
|
319
|
+
- Your own code
|
|
320
|
+
|
|
321
|
+
### How do I add another project?
|
|
322
|
+
|
|
323
|
+
Use the CLI command `nibs new <directory>`. Or you may manually create a new folder with a `src/` subdirectory containing your TypeScript files.
|
|
324
|
+
|
|
325
|
+
### Legacy Projects (v3.x and earlier)
|
|
326
|
+
|
|
327
|
+
If you're upgrading from the older npm-run-script based version:
|
|
328
|
+
|
|
329
|
+
1. **Install the CLI tool**:
|
|
330
|
+
```bash
|
|
331
|
+
npm install -g nibs-cli
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
2. **Move your projects** out of the repository's `projects/` folder and into your own source control repository
|
|
335
|
+
|
|
336
|
+
3. **Update your workflow**:
|
|
337
|
+
- Old: `npm run build -- my-project`
|
|
338
|
+
- New: `cd my-project && nibs build`
|
|
339
|
+
|
|
340
|
+
The old multi-project-folder structure is no longer supported. Each script should now be managed in its own directory.
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
MIT License - feel free to use this CLI tool for your NovelAI script projects!
|
|
345
|
+
|
|
346
|
+
## Resources
|
|
347
|
+
|
|
348
|
+
- **[NovelAI Scripting Documentation](https://docs.novelai.net/scripting/introduction.html)**
|
|
349
|
+
- **[NovelAI API Reference](https://docs.novelai.net/en/scripting/api-reference)**
|
|
350
|
+
- **[TypeScript Documentation](https://www.typescriptlang.org/docs/)**
|
|
351
|
+
- **[NovelAI Discord](https://discord.gg/novelai)**
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
**Ready to start?** Run `nibs new my-script` and start building your NovelAI scripts!
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const process_1 = require("process");
|
|
8
|
+
const build_1 = require("./commands/build");
|
|
9
|
+
const new_1 = require("./commands/new");
|
|
10
|
+
const project_1 = require("./commands/project");
|
|
11
|
+
const watch_1 = require("./commands/watch");
|
|
12
|
+
const fetch_1 = require("./utils/fetch");
|
|
13
|
+
// Helpers
|
|
14
|
+
async function ensureTypesFile(projectPath) {
|
|
15
|
+
try {
|
|
16
|
+
const stats = await (0, promises_1.stat)((0, path_1.join)(projectPath, "external", "script-types.d.ts"));
|
|
17
|
+
const age = Date.now() - stats.mtimeMs;
|
|
18
|
+
const hoursOld = age / (1000 * 60 * 60);
|
|
19
|
+
if (hoursOld < 24) {
|
|
20
|
+
console.log("✓ Using cached NovelAI type definitions");
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
await (0, fetch_1.fetchExternalTypes)(projectPath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
await (0, fetch_1.fetchExternalTypes)(projectPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
commander_1.program.description("NovelAI Script Build System").version("4.0.0");
|
|
31
|
+
commander_1.program.command("new [directory]").action((directory = ".") => {
|
|
32
|
+
const projectPath = (0, path_1.resolve)((0, process_1.cwd)(), directory);
|
|
33
|
+
(0, new_1.createNewProject)(projectPath);
|
|
34
|
+
});
|
|
35
|
+
commander_1.program
|
|
36
|
+
.command("build [directory]", { isDefault: true })
|
|
37
|
+
.description("Build project")
|
|
38
|
+
.action(async (directory = ".") => {
|
|
39
|
+
const projectPath = (0, path_1.resolve)((0, process_1.cwd)(), directory);
|
|
40
|
+
await ensureTypesFile(projectPath);
|
|
41
|
+
try {
|
|
42
|
+
const project = await (0, project_1.loadProject)(projectPath);
|
|
43
|
+
await (0, build_1.buildProject)(project);
|
|
44
|
+
console.log(`\n✅ Build complete!`);
|
|
45
|
+
// Show output file size
|
|
46
|
+
const outputPath = (0, path_1.join)((0, path_1.join)(projectPath, "dist"), `${project.name}.naiscript`);
|
|
47
|
+
const stats = await (0, promises_1.stat)(outputPath);
|
|
48
|
+
const sizeKB = (stats.size / 1024).toFixed(2);
|
|
49
|
+
console.log(`✅ Built: dist/${project.name}.naiscript (${sizeKB} KB)`);
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.log("Build error:", err);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
commander_1.program
|
|
58
|
+
.command("watch [directory]")
|
|
59
|
+
.description("Automatically watch and rebuild project on changes.")
|
|
60
|
+
.action(async (directory = ".") => {
|
|
61
|
+
const projectPath = (0, path_1.resolve)((0, process_1.cwd)(), directory);
|
|
62
|
+
await ensureTypesFile(projectPath);
|
|
63
|
+
try {
|
|
64
|
+
const project = await (0, project_1.loadProject)(projectPath);
|
|
65
|
+
const watcher = (0, watch_1.watchProject)(project);
|
|
66
|
+
["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => process.on(signal, () => {
|
|
67
|
+
console.log(" Cleaning up, closing watcher");
|
|
68
|
+
watcher.close();
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.log(`Watch error: ${err.message}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
commander_1.program.parse();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildProject = buildProject;
|
|
4
|
+
const promises_1 = require("fs/promises");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const rollup_1 = require("rollup");
|
|
7
|
+
const project_1 = require("./project");
|
|
8
|
+
const rollup_config_1 = require("./rollup-config");
|
|
9
|
+
async function buildProject(project) {
|
|
10
|
+
const { name, path, meta } = project;
|
|
11
|
+
console.log(`\n🔨 Building project: ${name}`);
|
|
12
|
+
meta.set("updatedAt", (0, project_1.currentEpochS)());
|
|
13
|
+
await (0, rollup_1.rollup)((0, rollup_config_1.rollupInputOptions)(project)).then((bundle) => bundle.write((0, rollup_config_1.rollupOutputOptions)(project)).then(() => bundle.close()));
|
|
14
|
+
// Write new project.yaml file
|
|
15
|
+
await (0, promises_1.writeFile)((0, path_1.join)(path, "project.yaml"), meta.toString()).catch(console.error);
|
|
16
|
+
return true;
|
|
17
|
+
}
|