@luzzle/cli 0.0.125

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.
Files changed (90) hide show
  1. package/README.md +53 -0
  2. package/dist/src/index.d.ts +2 -0
  3. package/dist/src/index.js +4 -0
  4. package/dist/src/index.js.map +1 -0
  5. package/dist/src/lib/cli.d.ts +2 -0
  6. package/dist/src/lib/cli.js +112 -0
  7. package/dist/src/lib/cli.js.map +1 -0
  8. package/dist/src/lib/cli.test.d.ts +1 -0
  9. package/dist/src/lib/cli.test.js +197 -0
  10. package/dist/src/lib/cli.test.js.map +1 -0
  11. package/dist/src/lib/commands/command/assistant.d.ts +11 -0
  12. package/dist/src/lib/commands/command/assistant.js +67 -0
  13. package/dist/src/lib/commands/command/assistant.js.map +1 -0
  14. package/dist/src/lib/commands/command/assistant.test.d.ts +1 -0
  15. package/dist/src/lib/commands/command/assistant.test.js +161 -0
  16. package/dist/src/lib/commands/command/assistant.test.js.map +1 -0
  17. package/dist/src/lib/commands/command/config.d.ts +8 -0
  18. package/dist/src/lib/commands/command/config.js +67 -0
  19. package/dist/src/lib/commands/command/config.js.map +1 -0
  20. package/dist/src/lib/commands/command/config.test.d.ts +1 -0
  21. package/dist/src/lib/commands/command/config.test.js +113 -0
  22. package/dist/src/lib/commands/command/config.test.js.map +1 -0
  23. package/dist/src/lib/commands/command/create.d.ts +10 -0
  24. package/dist/src/lib/commands/command/create.js +63 -0
  25. package/dist/src/lib/commands/command/create.js.map +1 -0
  26. package/dist/src/lib/commands/command/create.test.d.ts +1 -0
  27. package/dist/src/lib/commands/command/create.test.js +126 -0
  28. package/dist/src/lib/commands/command/create.test.js.map +1 -0
  29. package/dist/src/lib/commands/command/field.d.ts +10 -0
  30. package/dist/src/lib/commands/command/field.js +90 -0
  31. package/dist/src/lib/commands/command/field.js.map +1 -0
  32. package/dist/src/lib/commands/command/field.test.d.ts +1 -0
  33. package/dist/src/lib/commands/command/field.test.js +395 -0
  34. package/dist/src/lib/commands/command/field.test.js.map +1 -0
  35. package/dist/src/lib/commands/command/init.d.ts +6 -0
  36. package/dist/src/lib/commands/command/init.js +42 -0
  37. package/dist/src/lib/commands/command/init.js.map +1 -0
  38. package/dist/src/lib/commands/command/init.test.d.ts +1 -0
  39. package/dist/src/lib/commands/command/init.test.js +84 -0
  40. package/dist/src/lib/commands/command/init.test.js.map +1 -0
  41. package/dist/src/lib/commands/command/sync.d.ts +7 -0
  42. package/dist/src/lib/commands/command/sync.js +85 -0
  43. package/dist/src/lib/commands/command/sync.js.map +1 -0
  44. package/dist/src/lib/commands/command/sync.test.d.ts +1 -0
  45. package/dist/src/lib/commands/command/sync.test.js +117 -0
  46. package/dist/src/lib/commands/command/sync.test.js.map +1 -0
  47. package/dist/src/lib/commands/command/validate.d.ts +5 -0
  48. package/dist/src/lib/commands/command/validate.js +22 -0
  49. package/dist/src/lib/commands/command/validate.js.map +1 -0
  50. package/dist/src/lib/commands/command/validate.test.d.ts +1 -0
  51. package/dist/src/lib/commands/command/validate.test.js +59 -0
  52. package/dist/src/lib/commands/command/validate.test.js.map +1 -0
  53. package/dist/src/lib/commands/index.d.ts +6 -0
  54. package/dist/src/lib/commands/index.js +19 -0
  55. package/dist/src/lib/commands/index.js.map +1 -0
  56. package/dist/src/lib/commands/index.test.d.ts +1 -0
  57. package/dist/src/lib/commands/index.test.js +31 -0
  58. package/dist/src/lib/commands/index.test.js.map +1 -0
  59. package/dist/src/lib/commands/utils/context.fixtures.d.ts +23 -0
  60. package/dist/src/lib/commands/utils/context.fixtures.js +76 -0
  61. package/dist/src/lib/commands/utils/context.fixtures.js.map +1 -0
  62. package/dist/src/lib/commands/utils/pieces.d.ts +27 -0
  63. package/dist/src/lib/commands/utils/pieces.js +47 -0
  64. package/dist/src/lib/commands/utils/pieces.js.map +1 -0
  65. package/dist/src/lib/commands/utils/pieces.test.d.ts +1 -0
  66. package/dist/src/lib/commands/utils/pieces.test.js +97 -0
  67. package/dist/src/lib/commands/utils/pieces.test.js.map +1 -0
  68. package/dist/src/lib/config.d.ts +35 -0
  69. package/dist/src/lib/config.js +145 -0
  70. package/dist/src/lib/config.js.map +1 -0
  71. package/dist/src/lib/config.mock.d.ts +5 -0
  72. package/dist/src/lib/config.mock.js +10 -0
  73. package/dist/src/lib/config.mock.js.map +1 -0
  74. package/dist/src/lib/config.test.d.ts +1 -0
  75. package/dist/src/lib/config.test.js +129 -0
  76. package/dist/src/lib/config.test.js.map +1 -0
  77. package/dist/src/lib/database.mock.d.ts +22 -0
  78. package/dist/src/lib/database.mock.js +34 -0
  79. package/dist/src/lib/database.mock.js.map +1 -0
  80. package/dist/src/lib/log.d.ts +2 -0
  81. package/dist/src/lib/log.js +9 -0
  82. package/dist/src/lib/log.js.map +1 -0
  83. package/dist/src/version.d.ts +2 -0
  84. package/dist/src/version.js +2 -0
  85. package/dist/src/version.js.map +1 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -0
  87. package/dist/vite.config.d.ts +2 -0
  88. package/dist/vite.config.js +38 -0
  89. package/dist/vite.config.js.map +1 -0
  90. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # @luzzle/cli
2
+
3
+ The trusty command-line companion for Luzzle. 🛠️
4
+
5
+ ## Overview
6
+
7
+ The Luzzle CLI handles the mundane tasks—like validating schemas and organizing
8
+ assets—so you can focus on the fun part: hoarding data. 🗄️
9
+
10
+ It streamlines the creation of new pieces and ensures everything in your archive
11
+ is neat and tidy.
12
+
13
+ ## Usage
14
+
15
+ You can install it globally (live dangerously) or just run it via `npx`.
16
+
17
+ ```bash
18
+ npm install -g @luzzle/cli
19
+ ```
20
+
21
+ *(Installation usually takes a few seconds. Just enough time for a sip of
22
+ water. 💧)*
23
+
24
+ ### Common Commands
25
+
26
+ * **Initialize:** `luzzle init`
27
+ * **Create Piece:** `luzzle piece add book --title "The Hobbit"`
28
+ * **Validate:** `luzzle validate`
29
+
30
+ ## Features
31
+
32
+ * **Schema-Aware:** Uses your `.luzzle` definitions to prompt for the right
33
+ fields. Smart! 🧠
34
+ * **Asset Handling:** Automatically organizes images into `.assets`.
35
+
36
+ ### Configuration
37
+
38
+ The CLI supports a configuration file to manage settings.
39
+
40
+ #### Managing Config
41
+
42
+ * **View Configuration:** `luzzle config`
43
+ * **Get a Value:** `luzzle config storage.type`
44
+ * **Set a Value:** `luzzle config storage.type filesystem`
45
+ * **Remove a Value:** `luzzle config --remove api_keys.google`
46
+
47
+ #### Configuration Options
48
+
49
+ The YAML configuration supports:
50
+
51
+ * **storage:** `filesystem` (default) or `webdav`.
52
+ * **database:** `sqlite` (the only one you need).
53
+ * **api_keys:** For when you need a little AI help. 🤖
@@ -0,0 +1,2 @@
1
+ #! /usr/bin/env node
2
+ export {};
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/env node
2
+ import run from './lib/cli.js';
3
+ run().then();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,GAAG,MAAM,cAAc,CAAA;AAC9B,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare function run(): Promise<void>;
2
+ export default run;
@@ -0,0 +1,112 @@
1
+ import { getDatabaseClient, migrate } from '@luzzle/core';
2
+ import { getConfig, getDatabasePath, getStorage } from './config.js';
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import log from './log.js';
6
+ import getCommands from './commands/index.js';
7
+ import VERSION from '../version.js';
8
+ import { Pieces } from '@luzzle/core';
9
+ async function parseArgs(_args, commands) {
10
+ const cli = yargs(_args)
11
+ .strict()
12
+ .options({
13
+ 'dry-run': {
14
+ type: 'boolean',
15
+ description: 'run without making permanent changes',
16
+ default: false,
17
+ },
18
+ verbose: {
19
+ type: 'boolean',
20
+ default: false,
21
+ },
22
+ config: {
23
+ alias: 'c',
24
+ type: 'string',
25
+ description: 'Path to config file',
26
+ },
27
+ })
28
+ .demandCommand(1, `[error] please specify a command`)
29
+ .help()
30
+ .version(VERSION)
31
+ .showHelpOnFail(false);
32
+ const cliCommands = Object.values(commands).reduce((cli, command) => cli.command(command.command, command.describe, (yargs) => command.builder?.(yargs)), cli);
33
+ const fullCommand = await cliCommands.parseAsync();
34
+ return {
35
+ name: fullCommand._[0],
36
+ options: fullCommand,
37
+ };
38
+ }
39
+ async function cleanup(ctx) {
40
+ await ctx.db.destroy();
41
+ }
42
+ async function initialize(command, parsedArgs) {
43
+ const config = getConfig(parsedArgs.options.config);
44
+ const storage = getStorage(config);
45
+ const db = {};
46
+ const ctx = {
47
+ db,
48
+ log,
49
+ storage: getStorage(config),
50
+ pieces: new Pieces(storage),
51
+ config,
52
+ flags: {
53
+ dryRun: parsedArgs.options.dryRun,
54
+ },
55
+ };
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ await command.run(ctx, parsedArgs.options);
58
+ }
59
+ async function handle(commands, parsedArgs) {
60
+ const config = getConfig(parsedArgs.options.config);
61
+ const storage = getStorage(config);
62
+ const dbPath = getDatabasePath(config);
63
+ const db = getDatabaseClient(dbPath);
64
+ const ctx = {
65
+ db,
66
+ log,
67
+ storage: storage,
68
+ pieces: new Pieces(storage),
69
+ config,
70
+ flags: {
71
+ dryRun: parsedArgs.options.dryRun,
72
+ },
73
+ };
74
+ const migrationStatus = await migrate(ctx.db);
75
+ if (!migrationStatus.error) {
76
+ await Object.values(commands)
77
+ .find((c) => c.name === parsedArgs.name)
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ ?.run(ctx, parsedArgs.options);
80
+ }
81
+ else {
82
+ log.error(migrationStatus.error);
83
+ }
84
+ await cleanup(ctx);
85
+ }
86
+ async function run() {
87
+ const commands = await getCommands();
88
+ try {
89
+ const parsedArgs = await parseArgs(hideBin(process.argv), commands);
90
+ log.level = parsedArgs.options.verbose ? 'info' : 'warn';
91
+ if (parsedArgs.options.dryRun) {
92
+ log.child({ dryRun: true }, { level: 'info' });
93
+ log.level = 'info';
94
+ }
95
+ if (parsedArgs.name === 'init') {
96
+ await initialize(commands.init, parsedArgs);
97
+ }
98
+ else {
99
+ await handle(commands, parsedArgs);
100
+ }
101
+ }
102
+ catch (err) {
103
+ if (err instanceof Error) {
104
+ log.error(err?.stack);
105
+ }
106
+ else {
107
+ log.error(err);
108
+ }
109
+ }
110
+ }
111
+ export default run;
112
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/lib/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,197 @@
1
+ import { getDatabaseClient, migrate } from '@luzzle/core';
2
+ import log from './log.js';
3
+ import cli from './cli.js';
4
+ import { describe, expect, test, vi, afterEach } from 'vitest';
5
+ import { getDatabasePath, getConfig } from './config.js';
6
+ import getCommands from './commands/index.js';
7
+ import { mockDatabase } from './database.mock.js';
8
+ vi.mock('@luzzle/core');
9
+ vi.mock('./config.js');
10
+ vi.mock('./commands/index.js', () => { return { default: vi.fn() }; });
11
+ vi.mock('./log.js');
12
+ const mocks = {
13
+ logInfo: vi.spyOn(log, 'info'),
14
+ logError: vi.spyOn(log, 'error'),
15
+ logChild: vi.spyOn(log, 'child'),
16
+ logLevelSet: vi.spyOn(log, 'level', 'set'),
17
+ getDatabaseClient: vi.mocked(getDatabaseClient),
18
+ getDatabasePath: vi.mocked(getDatabasePath),
19
+ getConfig: vi.mocked(getConfig),
20
+ migrate: vi.mocked(migrate),
21
+ getCommands: vi.mocked(getCommands),
22
+ };
23
+ const spies = [];
24
+ describe('lib/cli', () => {
25
+ afterEach(() => {
26
+ Object.values(mocks).forEach((mock) => {
27
+ mock.mockReset();
28
+ });
29
+ spies.forEach((spy) => {
30
+ spy.mockRestore();
31
+ });
32
+ });
33
+ test(`run init`, async () => {
34
+ const config = {};
35
+ const run = vi.fn();
36
+ const name = 'init';
37
+ mocks.getConfig.mockReturnValueOnce(config);
38
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
39
+ mocks.getCommands.mockResolvedValueOnce({
40
+ init: {
41
+ run,
42
+ name,
43
+ command: 'init [directory]',
44
+ describe: 'init description',
45
+ builder: vi.fn()
46
+ },
47
+ });
48
+ process.argv = ['node', 'cli', name, 'test'];
49
+ await cli();
50
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('warn');
51
+ expect(run).toHaveBeenCalledOnce();
52
+ });
53
+ test(`run init with dryRun`, async () => {
54
+ const config = {};
55
+ const run = vi.fn();
56
+ const name = 'init';
57
+ mocks.getConfig.mockReturnValueOnce(config);
58
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
59
+ mocks.getCommands.mockResolvedValueOnce({
60
+ init: {
61
+ run,
62
+ name,
63
+ command: 'init [directory]',
64
+ describe: 'init description',
65
+ builder: vi.fn()
66
+ },
67
+ });
68
+ process.argv = ['node', 'cli', name, '--dry-run', 'test'];
69
+ await cli();
70
+ expect(mocks.logChild).toHaveBeenCalledWith({ dryRun: true }, { level: 'info' });
71
+ expect(run).toHaveBeenCalledOnce();
72
+ });
73
+ test(`run test command`, async () => {
74
+ const config = {};
75
+ const kysely = mockDatabase();
76
+ const run = vi.fn();
77
+ const name = 'command1';
78
+ mocks.getConfig.mockReturnValueOnce(config);
79
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
80
+ mocks.getDatabaseClient.mockReturnValueOnce(kysely.db);
81
+ mocks.migrate.mockResolvedValueOnce({});
82
+ mocks.getCommands.mockResolvedValueOnce({
83
+ command1: {
84
+ run,
85
+ name,
86
+ command: 'command1',
87
+ describe: 'command1 description',
88
+ builder: vi.fn()
89
+ },
90
+ });
91
+ process.argv = ['node', 'cli', name];
92
+ await cli();
93
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('warn');
94
+ expect(run).toHaveBeenCalledOnce();
95
+ expect(kysely.db.destroy).toHaveBeenCalledOnce();
96
+ });
97
+ test(`run test command with verbose`, async () => {
98
+ const config = {};
99
+ const kysely = mockDatabase();
100
+ const run = vi.fn();
101
+ const name = 'command1';
102
+ mocks.getConfig.mockReturnValueOnce(config);
103
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
104
+ mocks.getDatabaseClient.mockReturnValueOnce(kysely.db);
105
+ mocks.migrate.mockResolvedValueOnce({});
106
+ mocks.getCommands.mockResolvedValueOnce({
107
+ command1: {
108
+ run,
109
+ name,
110
+ command: 'command1',
111
+ describe: 'command1 description',
112
+ builder: vi.fn()
113
+ },
114
+ });
115
+ process.argv = ['node', 'cli', name, '--verbose'];
116
+ await cli();
117
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('info');
118
+ expect(run).toHaveBeenCalledOnce();
119
+ expect(kysely.db.destroy).toHaveBeenCalledOnce();
120
+ });
121
+ test(`run fails migration on test command`, async () => {
122
+ const config = {};
123
+ const kysely = mockDatabase();
124
+ const run = vi.fn();
125
+ const name = 'command1';
126
+ mocks.getConfig.mockReturnValueOnce(config);
127
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
128
+ mocks.getDatabaseClient.mockReturnValueOnce(kysely.db);
129
+ mocks.migrate.mockResolvedValueOnce({ error: 'some error' });
130
+ mocks.getCommands.mockResolvedValueOnce({
131
+ command1: {
132
+ run,
133
+ name,
134
+ command: 'command1',
135
+ describe: 'command1 description',
136
+ builder: vi.fn()
137
+ },
138
+ });
139
+ process.argv = ['node', 'cli', name];
140
+ await cli();
141
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('warn');
142
+ expect(mocks.logError).toHaveBeenCalledOnce();
143
+ expect(run).not.toHaveBeenCalled();
144
+ expect(kysely.db.destroy).toHaveBeenCalledOnce();
145
+ });
146
+ test(`run catches an error`, async () => {
147
+ const config = {};
148
+ const kysely = mockDatabase();
149
+ const run = vi.fn();
150
+ const name = 'command1';
151
+ mocks.getConfig.mockReturnValueOnce(config);
152
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
153
+ mocks.getDatabaseClient.mockReturnValueOnce(kysely.db);
154
+ mocks.migrate.mockResolvedValueOnce({});
155
+ mocks.getCommands.mockResolvedValueOnce({
156
+ command1: {
157
+ run,
158
+ name,
159
+ command: 'command1',
160
+ describe: 'command1 description',
161
+ builder: vi.fn()
162
+ },
163
+ });
164
+ run.mockRejectedValueOnce(new Error('oops'));
165
+ process.argv = ['node', 'cli', name];
166
+ await cli();
167
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('warn');
168
+ expect(run).toHaveBeenCalledOnce();
169
+ expect(mocks.logError).toHaveBeenCalledOnce();
170
+ });
171
+ test(`run catches a rejection`, async () => {
172
+ const config = {};
173
+ const kysely = mockDatabase();
174
+ const run = vi.fn();
175
+ const name = 'command1';
176
+ mocks.getConfig.mockReturnValueOnce(config);
177
+ mocks.getDatabasePath.mockReturnValueOnce('somewhere');
178
+ mocks.getDatabaseClient.mockReturnValueOnce(kysely.db);
179
+ mocks.migrate.mockResolvedValueOnce({});
180
+ mocks.getCommands.mockResolvedValueOnce({
181
+ command1: {
182
+ run,
183
+ name,
184
+ command: 'command1',
185
+ describe: 'command1 description',
186
+ builder: vi.fn()
187
+ },
188
+ });
189
+ run.mockRejectedValueOnce('oops');
190
+ process.argv = ['node', 'cli', name];
191
+ await cli();
192
+ expect(mocks.logLevelSet).toHaveBeenCalledWith('warn');
193
+ expect(run).toHaveBeenCalledOnce();
194
+ expect(mocks.logError).toHaveBeenCalledOnce();
195
+ });
196
+ });
197
+ //# sourceMappingURL=cli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../../src/lib/cli.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Command } from '../utils/types.js';
2
+ import { PieceArgv } from '../utils/pieces.js';
3
+ export type AssistantArgv = {
4
+ update?: string;
5
+ directory?: string;
6
+ prompt: string;
7
+ file?: Array<string>;
8
+ title?: string;
9
+ } & PieceArgv;
10
+ declare const command: Command<AssistantArgv>;
11
+ export default command;
@@ -0,0 +1,67 @@
1
+ import yaml from 'yaml';
2
+ import { makePieceOption, parsePieceOptionArgv } from '../utils/pieces.js';
3
+ import { pieceFrontMatterFromPrompt } from '@luzzle/core';
4
+ const command = {
5
+ name: 'assistant',
6
+ command: `assistant`,
7
+ describe: 'prompt an assistant to generate a piece',
8
+ builder: function (yargs) {
9
+ return makePieceOption(yargs)
10
+ .option('update', {
11
+ alias: 'u',
12
+ type: 'string',
13
+ description: 'file path to an existing piece',
14
+ })
15
+ .option('directory', {
16
+ alias: 'd',
17
+ type: 'string',
18
+ description: 'dir to where you want to create the piece',
19
+ })
20
+ .option('title', {
21
+ type: 'string',
22
+ description: 'title of the piece you want to create',
23
+ })
24
+ .option('prompt', {
25
+ type: 'string',
26
+ description: 'a sentence or two explaining what the piece is about and where to find more information about the piece',
27
+ demandOption: true,
28
+ })
29
+ .option('file', {
30
+ type: 'string',
31
+ array: true,
32
+ description: 'path to a file (pdf,txt,html,json,png,jpeg) associated with the piece, can specify multiple times',
33
+ });
34
+ },
35
+ run: async function (ctx, args) {
36
+ const { prompt, file, update, directory, title } = args;
37
+ const { piece } = await parsePieceOptionArgv(ctx, args);
38
+ const apiKey = ctx.config.get('api_keys.google', '');
39
+ const metadata = await pieceFrontMatterFromPrompt(apiKey, piece.schema, prompt, file);
40
+ if (update && directory) {
41
+ throw new Error(`update and directory are mutually exclusive`);
42
+ }
43
+ if (update && title) {
44
+ throw new Error(`title is only to be used when creating a new piece`);
45
+ }
46
+ if (directory && !title) {
47
+ throw new Error(`title is required when creating a new piece`);
48
+ }
49
+ if (update) {
50
+ const markdown = await piece.get(update);
51
+ const markdownUpdate = await piece.setFields(markdown, metadata);
52
+ await piece.write(markdownUpdate);
53
+ console.log(yaml.stringify(markdownUpdate.frontmatter));
54
+ }
55
+ else if (directory && title) {
56
+ const markdown = await piece.create(directory, title);
57
+ const markdownUpdate = await piece.setFields(markdown, metadata);
58
+ await piece.write(markdownUpdate);
59
+ console.log(yaml.stringify(markdownUpdate.frontmatter));
60
+ }
61
+ else {
62
+ console.log(yaml.stringify(metadata));
63
+ }
64
+ },
65
+ };
66
+ export default command;
67
+ //# sourceMappingURL=assistant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../../../src/lib/commands/command/assistant.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,161 @@
1
+ import log from '../../log.js';
2
+ import { describe, expect, test, vi, afterEach } from 'vitest';
3
+ import command from './assistant.js';
4
+ import yargs from 'yargs';
5
+ import { makeContext, makeMarkdownSample, makePieceMock } from '../utils/context.fixtures.js';
6
+ import { makePieceOption, parsePieceOptionArgv } from '../utils/pieces.js';
7
+ import yaml from 'yaml';
8
+ import { pieceFrontMatterFromPrompt } from '@luzzle/core';
9
+ vi.mock('@luzzle/core');
10
+ vi.mock('../utils/pieces.js');
11
+ vi.mock('../../log.js');
12
+ vi.mock('yaml');
13
+ const mocks = {
14
+ logError: vi.spyOn(log, 'error'),
15
+ logInfo: vi.spyOn(log, 'info'),
16
+ parseArgs: vi.mocked(parsePieceOptionArgv),
17
+ makeOption: vi.mocked(makePieceOption),
18
+ generatePieceFrontmatter: vi.mocked(pieceFrontMatterFromPrompt),
19
+ getPiece: vi.fn(),
20
+ consoleLog: vi.spyOn(console, 'log'),
21
+ yamlStringify: vi.mocked(yaml.stringify),
22
+ };
23
+ const spies = {};
24
+ describe('lib/commands/assistant.ts', () => {
25
+ afterEach(() => {
26
+ Object.values(mocks).forEach((mock) => {
27
+ mock.mockReset();
28
+ });
29
+ Object.keys(spies).forEach((key) => {
30
+ spies[key].mockRestore();
31
+ delete spies[key];
32
+ });
33
+ });
34
+ test('run', async () => {
35
+ const apiKeys = 'api_key';
36
+ const piece = makePieceMock();
37
+ const frontmatter = makeMarkdownSample().frontmatter;
38
+ const prompt = 'prompt';
39
+ const ctx = makeContext({
40
+ config: {
41
+ get: vi.fn().mockReturnValueOnce(apiKeys),
42
+ },
43
+ });
44
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
45
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
46
+ await command.run(ctx, { prompt });
47
+ expect(mocks.yamlStringify).toHaveBeenCalledOnce();
48
+ expect(mocks.consoleLog).toHaveBeenCalledOnce();
49
+ expect(mocks.generatePieceFrontmatter).toHaveBeenCalledWith(apiKeys, piece.schema, prompt, undefined);
50
+ });
51
+ test('must use update and create exclusively', async () => {
52
+ const update = 'path/to/piece';
53
+ const directory = 'path/to/folder';
54
+ const apiKeys = 'api_key';
55
+ const piece = makePieceMock();
56
+ const frontmatter = makeMarkdownSample().frontmatter;
57
+ const prompt = 'prompt';
58
+ const ctx = makeContext({
59
+ config: {
60
+ get: vi.fn().mockReturnValueOnce(apiKeys),
61
+ },
62
+ });
63
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
64
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
65
+ const creating = command.run(ctx, { prompt, update, directory });
66
+ await expect(creating).rejects.toThrow();
67
+ });
68
+ test('must use update and title exclusively', async () => {
69
+ const update = 'path/to/piece';
70
+ const title = 'title';
71
+ const apiKeys = 'api_key';
72
+ const piece = makePieceMock();
73
+ const frontmatter = makeMarkdownSample().frontmatter;
74
+ const prompt = 'prompt';
75
+ const ctx = makeContext({
76
+ config: {
77
+ get: vi.fn().mockReturnValueOnce(apiKeys),
78
+ },
79
+ });
80
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
81
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
82
+ const creating = command.run(ctx, { prompt, update, title });
83
+ await expect(creating).rejects.toThrow();
84
+ });
85
+ test('updates a piece', async () => {
86
+ const update = 'path/to/piece';
87
+ const apiKeys = 'api_key';
88
+ const piece = makePieceMock();
89
+ const markdown = makeMarkdownSample();
90
+ const frontmatter = markdown.frontmatter;
91
+ const prompt = 'prompt';
92
+ const ctx = makeContext({
93
+ config: {
94
+ get: vi.fn().mockReturnValueOnce(apiKeys),
95
+ },
96
+ });
97
+ spies.pieceGet = vi.spyOn(piece, 'get').mockResolvedValueOnce(markdown);
98
+ spies.pieceWrite = vi.spyOn(piece, 'write').mockResolvedValueOnce();
99
+ spies.pieceSetFields = vi
100
+ .spyOn(piece, 'setFields')
101
+ .mockResolvedValueOnce(markdown);
102
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
103
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
104
+ await command.run(ctx, { prompt, update });
105
+ expect(spies.pieceGet).toHaveBeenCalledWith(update);
106
+ expect(spies.pieceWrite).toHaveBeenCalledWith({ ...markdown, frontmatter });
107
+ expect(spies.pieceSetFields).toHaveBeenCalledWith(markdown, frontmatter);
108
+ });
109
+ test('must have a title when creating', async () => {
110
+ const directory = 'path/to/folder';
111
+ const apiKeys = 'api_key';
112
+ const piece = makePieceMock();
113
+ const frontmatter = makeMarkdownSample().frontmatter;
114
+ const prompt = 'prompt';
115
+ const ctx = makeContext({
116
+ config: {
117
+ get: vi.fn().mockReturnValueOnce(apiKeys),
118
+ },
119
+ });
120
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
121
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
122
+ const creating = command.run(ctx, { prompt, directory });
123
+ await expect(creating).rejects.toThrow();
124
+ });
125
+ test('creates a new piece', async () => {
126
+ const directory = 'path/to/folder';
127
+ const title = 'title';
128
+ const apiKeys = 'api_key';
129
+ const piece = makePieceMock();
130
+ const markdown = makeMarkdownSample();
131
+ const frontmatter = markdown.frontmatter;
132
+ const prompt = 'prompt';
133
+ const ctx = makeContext({
134
+ config: {
135
+ get: vi.fn().mockReturnValueOnce(apiKeys),
136
+ },
137
+ });
138
+ spies.pieceCreate = vi.spyOn(piece, 'create').mockResolvedValueOnce(markdown);
139
+ spies.pieceWrite = vi.spyOn(piece, 'write').mockResolvedValueOnce();
140
+ spies.pieceSetFields = vi
141
+ .spyOn(piece, 'setFields')
142
+ .mockResolvedValueOnce(markdown);
143
+ mocks.parseArgs.mockResolvedValueOnce({ piece });
144
+ mocks.generatePieceFrontmatter.mockResolvedValueOnce(frontmatter);
145
+ await command.run(ctx, { prompt, directory, title });
146
+ expect(spies.pieceCreate).toHaveBeenCalledWith(directory, title);
147
+ expect(spies.pieceWrite).toHaveBeenCalledWith({ ...markdown, frontmatter });
148
+ expect(spies.pieceSetFields).toHaveBeenCalledWith(markdown, frontmatter);
149
+ });
150
+ test('builder', async () => {
151
+ const args = yargs();
152
+ mocks.makeOption.mockReturnValueOnce(args);
153
+ spies.positional = vi.spyOn(args, 'positional').mockReturnValue(args);
154
+ spies.option = vi.spyOn(args, 'option').mockReturnValue(args);
155
+ command.builder?.(args);
156
+ expect(spies.positional).toHaveBeenCalledTimes(0);
157
+ expect(spies.option).toHaveBeenCalledTimes(5);
158
+ expect(mocks.makeOption).toHaveBeenCalledOnce();
159
+ });
160
+ });
161
+ //# sourceMappingURL=assistant.test.js.map