@forgehive/forge-cli 0.2.13 → 0.3.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.
Files changed (84) hide show
  1. package/dist/runner.js +15 -7
  2. package/dist/tasks/auth/add.js +23 -19
  3. package/dist/tasks/auth/list.js +20 -16
  4. package/dist/tasks/auth/load.js +19 -15
  5. package/dist/tasks/auth/loadCurrent.js +13 -9
  6. package/dist/tasks/auth/remove.js +30 -26
  7. package/dist/tasks/auth/switch.js +19 -15
  8. package/dist/tasks/bundle/create.js +16 -12
  9. package/dist/tasks/bundle/fingerprint.d.ts +36 -0
  10. package/dist/tasks/bundle/fingerprint.js +164 -0
  11. package/dist/tasks/bundle/load.js +9 -5
  12. package/dist/tasks/bundle/zip.js +49 -45
  13. package/dist/tasks/conf/info.js +23 -19
  14. package/dist/tasks/conf/load.js +8 -4
  15. package/dist/tasks/fixture/download.js +40 -36
  16. package/dist/tasks/init.js +35 -31
  17. package/dist/tasks/runner/bundle.js +34 -30
  18. package/dist/tasks/runner/create.js +28 -24
  19. package/dist/tasks/runner/remove.js +22 -18
  20. package/dist/tasks/task/createTask.js +35 -28
  21. package/dist/tasks/task/describe.d.ts +35 -0
  22. package/dist/tasks/task/describe.js +130 -0
  23. package/dist/tasks/task/download.js +63 -59
  24. package/dist/tasks/task/fingerprint.d.ts +26 -0
  25. package/dist/tasks/task/fingerprint.js +87 -0
  26. package/dist/tasks/task/list.d.ts +12 -0
  27. package/dist/tasks/task/list.js +46 -0
  28. package/dist/tasks/task/publish.js +72 -68
  29. package/dist/tasks/task/remove.js +24 -20
  30. package/dist/tasks/task/replay.js +94 -90
  31. package/dist/tasks/task/run.js +84 -79
  32. package/dist/test/setup.d.ts +0 -0
  33. package/dist/test/setup.js +14 -0
  34. package/dist/test/tasks/create.test.js +6 -5
  35. package/dist/utils/taskAnalysis.d.ts +21 -0
  36. package/dist/utils/taskAnalysis.js +380 -0
  37. package/forge.json +20 -0
  38. package/jest.config.js +2 -1
  39. package/logs/task:fingerprint.log +10 -0
  40. package/package.json +8 -8
  41. package/specs/fingerprint.md +380 -0
  42. package/src/runner.ts +14 -5
  43. package/src/tasks/README.md +13 -13
  44. package/src/tasks/auth/add.ts +3 -3
  45. package/src/tasks/auth/list.ts +3 -3
  46. package/src/tasks/auth/load.ts +3 -3
  47. package/src/tasks/auth/loadCurrent.ts +3 -3
  48. package/src/tasks/auth/remove.ts +3 -3
  49. package/src/tasks/auth/switch.ts +3 -3
  50. package/src/tasks/bundle/README.md +7 -7
  51. package/src/tasks/bundle/create.ts +4 -4
  52. package/src/tasks/bundle/fingerprint.ts +218 -0
  53. package/src/tasks/bundle/load.ts +4 -4
  54. package/src/tasks/bundle/zip.ts +3 -3
  55. package/src/tasks/conf/info.ts +3 -3
  56. package/src/tasks/conf/load.ts +3 -3
  57. package/src/tasks/fixture/download.ts +3 -3
  58. package/src/tasks/init.ts +3 -3
  59. package/src/tasks/runner/bundle.ts +3 -3
  60. package/src/tasks/runner/create.ts +3 -3
  61. package/src/tasks/runner/remove.ts +3 -3
  62. package/src/tasks/task/createTask.ts +10 -7
  63. package/src/tasks/task/describe.ts +148 -0
  64. package/src/tasks/task/download.ts +3 -3
  65. package/src/tasks/task/fingerprint.ts +107 -0
  66. package/src/tasks/task/list.ts +58 -0
  67. package/src/tasks/task/publish.ts +3 -3
  68. package/src/tasks/task/remove.ts +3 -3
  69. package/src/tasks/task/replay.ts +3 -3
  70. package/src/tasks/task/run.ts +5 -4
  71. package/src/test/setup.ts +14 -0
  72. package/src/test/tasks/create.test.ts +9 -9
  73. package/src/utils/taskAnalysis.ts +419 -0
  74. package/dist/taskAdapter.d.ts +0 -34
  75. package/dist/taskAdapter.js +0 -85
  76. package/dist/templates/README.md +0 -23
  77. package/dist/templates/task.hbs +0 -27
  78. package/dist/test/utils.d.ts +0 -2
  79. package/dist/test/utils.js +0 -17
  80. package/logs/auth:list.log +0 -4
  81. package/logs/auth:load.log +0 -2
  82. package/logs/auth:loadCurrent.log +0 -1
  83. package/logs/conf:info.log +0 -2
  84. package/logs/runner:create.log +0 -4
@@ -69,10 +69,10 @@ const boundaries = {
69
69
  }
70
70
  }
71
71
 
72
- export const create = createTask(
72
+ export const create = createTask({
73
73
  schema,
74
74
  boundaries,
75
- async function ({ runnerName }, {
75
+ fn: async function ({ runnerName }, {
76
76
  persistRunner,
77
77
  loadConf,
78
78
  persistConf,
@@ -118,4 +118,4 @@ export const create = createTask(
118
118
  runnerName: formattedName
119
119
  }
120
120
  }
121
- )
121
+ })
@@ -32,10 +32,10 @@ const boundaries = {
32
32
  }
33
33
  }
34
34
 
35
- export const remove = createTask(
35
+ export const remove = createTask({
36
36
  schema,
37
37
  boundaries,
38
- async function ({ runnerName }, {
38
+ fn: async function ({ runnerName }, {
39
39
  loadConf,
40
40
  getCwd,
41
41
  removeRunner,
@@ -71,4 +71,4 @@ export const remove = createTask(
71
71
  runnerName: formattedName
72
72
  }
73
73
  }
74
- )
74
+ })
@@ -18,6 +18,7 @@ const TASK_TEMPLATE = `// TASK: {{ taskName }}
18
18
  import { createTask } from '@forgehive/task'
19
19
  import { Schema } from '@forgehive/schema'
20
20
 
21
+ const name = '{{ taskDescriptor }}'
21
22
  const description = 'Add task description here'
22
23
 
23
24
  const schema = new Schema({
@@ -30,10 +31,12 @@ const boundaries = {
30
31
  // example: readFile: async (path: string) => fs.readFile(path, 'utf-8')
31
32
  }
32
33
 
33
- export const {{ taskName }} = createTask(
34
+ export const {{ taskName }} = createTask({
35
+ name,
36
+ description,
34
37
  schema,
35
38
  boundaries,
36
- async function (argv, boundaries) {
39
+ fn: async function (argv, boundaries) {
37
40
  console.log('input:', argv)
38
41
  console.log('boundaries:', boundaries)
39
42
  // Your task implementation goes here
@@ -41,9 +44,8 @@ export const {{ taskName }} = createTask(
41
44
 
42
45
  return status
43
46
  }
44
- )
47
+ })
45
48
 
46
- {{ taskName }}.setDescription(description)
47
49
  `
48
50
 
49
51
  const schema = new Schema({
@@ -107,10 +109,10 @@ const boundaries = {
107
109
  }
108
110
  }
109
111
 
110
- export const createTaskCommand = createTask(
112
+ export const createTaskCommand = createTask({
111
113
  schema,
112
114
  boundaries,
113
- async function ({ descriptorName }, {
115
+ fn: async function ({ descriptorName }, {
114
116
  loadTemplate,
115
117
  persistTask,
116
118
  loadConf,
@@ -132,6 +134,7 @@ export const createTaskCommand = createTask(
132
134
  ==================================================
133
135
  Starting task creation!
134
136
  Creating: ${taskName}
137
+ Descriptor: ${descriptor}
135
138
  Dir: ${dir ?? ''}
136
139
  Into: ${taskPath}
137
140
  ==================================================
@@ -159,4 +162,4 @@ export const createTaskCommand = createTask(
159
162
 
160
163
  return { taskPath, fileName }
161
164
  }
162
- )
165
+ })
@@ -0,0 +1,148 @@
1
+ // TASK: describe
2
+ // Run this task with:
3
+ // forge task:run task:describe
4
+
5
+ import path from 'path'
6
+ import os from 'os'
7
+ import fs from 'fs/promises'
8
+
9
+ import { createTask } from '@forgehive/task'
10
+ import { Schema } from '@forgehive/schema'
11
+
12
+ import { create as bundleCreate } from '../bundle/create'
13
+ import { load as bundleLoad } from '../bundle/load'
14
+ import { load as loadConf } from '../conf/load'
15
+ import { type ForgeConf } from '../types'
16
+
17
+ const description = 'Describe a task with detailed information about its schema, boundaries and configuration'
18
+
19
+ const schema = new Schema({
20
+ descriptorName: Schema.string()
21
+ })
22
+
23
+ const boundaries = {
24
+ loadConf: loadConf.asBoundary(),
25
+ bundleCreate: bundleCreate.asBoundary(),
26
+ bundleLoad: bundleLoad.asBoundary(),
27
+ ensureBuildsFolder: async (): Promise<string> => {
28
+ const buildsPath = path.join(os.homedir(), '.forge', 'builds')
29
+ try {
30
+ await fs.access(buildsPath)
31
+ } catch {
32
+ await fs.mkdir(buildsPath, { recursive: true })
33
+ }
34
+
35
+ return buildsPath
36
+ }
37
+ }
38
+
39
+ export const describe = createTask({
40
+ schema,
41
+ boundaries,
42
+ fn: async function ({ descriptorName }, {
43
+ loadConf,
44
+ bundleCreate,
45
+ bundleLoad,
46
+ ensureBuildsFolder
47
+ }) {
48
+ // Load forge configuration
49
+ const forge: ForgeConf = await loadConf({})
50
+ const taskDescriptor = forge.tasks[descriptorName as keyof typeof forge.tasks]
51
+
52
+ if (taskDescriptor === undefined) {
53
+ throw new Error(`Task "${descriptorName}" is not defined in forge.json`)
54
+ }
55
+
56
+ // Prepare paths
57
+ const entryPoint = path.join(process.cwd(), taskDescriptor.path)
58
+ const buildsPath = await ensureBuildsFolder()
59
+ const outputFile = path.join(buildsPath, `${descriptorName}.js`)
60
+
61
+ // Bundle the task
62
+ await bundleCreate({
63
+ entryPoint,
64
+ outputFile
65
+ })
66
+
67
+ // Load the bundled task
68
+ const bundle = await bundleLoad({
69
+ bundlePath: outputFile
70
+ })
71
+
72
+ // Get the task handler
73
+ const task = bundle[taskDescriptor.handler]
74
+
75
+ if (!task) {
76
+ throw new Error(`Handler "${taskDescriptor.handler}" not found in bundle`)
77
+ }
78
+
79
+ console.log('===============================================')
80
+ console.log(`Task: ${descriptorName}`)
81
+ console.log('===============================================')
82
+ console.log(`Path: ${taskDescriptor.path}`)
83
+ console.log(`Handler: ${taskDescriptor.handler}`)
84
+
85
+ // Get task description
86
+ const taskDescription = task.getDescription?.() || 'No description available'
87
+ console.log(`Description: ${taskDescription}`)
88
+
89
+ console.log('')
90
+ console.log('Schema:')
91
+ console.log('-------')
92
+
93
+ // Get schema information
94
+ const taskSchema = task.getSchema?.()
95
+ if (taskSchema && taskSchema.shape) {
96
+ const schemaKeys = Object.keys(taskSchema.shape)
97
+ if (schemaKeys.length === 0) {
98
+ console.log(' No schema parameters defined')
99
+ } else {
100
+ schemaKeys.forEach(key => {
101
+ const field = taskSchema.shape[key]
102
+ const fieldType = field.type || 'unknown'
103
+ const fieldDescription = field.description || ''
104
+
105
+ if (fieldDescription) {
106
+ console.log(` • ${key} (${fieldType}): ${fieldDescription}`)
107
+ } else {
108
+ console.log(` • ${key} (${fieldType})`)
109
+ }
110
+ })
111
+ }
112
+ } else {
113
+ console.log(' No schema information available')
114
+ }
115
+
116
+ console.log('')
117
+ console.log('Boundaries:')
118
+ console.log('-----------')
119
+
120
+ // Get boundaries information
121
+ const taskBoundaries = task.getBoundaries?.()
122
+ if (taskBoundaries) {
123
+ const boundaryKeys = Object.keys(taskBoundaries)
124
+ if (boundaryKeys.length === 0) {
125
+ console.log(' No boundaries defined')
126
+ } else {
127
+ boundaryKeys.forEach(boundaryName => {
128
+ console.log(` • ${boundaryName}`)
129
+ })
130
+ }
131
+ } else {
132
+ console.log(' No boundary information available')
133
+ }
134
+
135
+ console.log('===============================================')
136
+
137
+ return {
138
+ name: descriptorName,
139
+ path: taskDescriptor.path,
140
+ handler: taskDescriptor.handler,
141
+ description: taskDescription,
142
+ schema: taskSchema?.shape || {},
143
+ boundaries: taskBoundaries ? Object.keys(taskBoundaries) : []
144
+ }
145
+ }
146
+ })
147
+
148
+ describe.setDescription(description)
@@ -90,10 +90,10 @@ const boundaries = {
90
90
  }
91
91
  }
92
92
 
93
- export const download = createTask(
93
+ export const download = createTask({
94
94
  schema,
95
95
  boundaries,
96
- async function ({ descriptorName, uuid }, {
96
+ fn: async function ({ descriptorName, uuid }, {
97
97
  downloadTask,
98
98
  getCwd,
99
99
  parseTaskName,
@@ -189,4 +189,4 @@ export const download = createTask(
189
189
  handler: response.handler
190
190
  }
191
191
  }
192
- )
192
+ })
@@ -0,0 +1,107 @@
1
+ // TASK: fingerprint
2
+ // Run this task with:
3
+ // forge task:run task:fingerprint --descriptorName task-name
4
+
5
+ import { createTask } from '@forgehive/task'
6
+ import { Schema } from '@forgehive/schema'
7
+ import fs from 'fs/promises'
8
+ import path from 'path'
9
+ import os from 'os'
10
+
11
+ import { load as loadConf } from '../conf/load'
12
+ import { analyzeTaskFile, TaskFingerprintOutput } from '../../utils/taskAnalysis'
13
+
14
+ interface FingerprintAnalysis {
15
+ taskFingerprint: TaskFingerprintOutput
16
+ }
17
+
18
+ const description = 'Analyze a specific task and generate detailed fingerprint without bundling'
19
+
20
+ const schema = new Schema({
21
+ descriptorName: Schema.string()
22
+ })
23
+
24
+ const boundaries = {
25
+ getCwd: async (): Promise<string> => {
26
+ return process.cwd()
27
+ },
28
+ loadConf: loadConf.asBoundary(),
29
+ readFile: async (filePath: string): Promise<string> => {
30
+ return fs.readFile(filePath, 'utf-8')
31
+ },
32
+ writeFile: async (filePath: string, content: string): Promise<void> => {
33
+ return fs.writeFile(filePath, content)
34
+ },
35
+ ensureForgeFolder: async (): Promise<string> => {
36
+ const forgePath = path.join(os.homedir(), '.forge')
37
+ try {
38
+ await fs.access(forgePath)
39
+ } catch {
40
+ await fs.mkdir(forgePath, { recursive: true })
41
+ }
42
+ return forgePath
43
+ }
44
+ }
45
+
46
+ export const fingerprint = createTask({
47
+ schema,
48
+ boundaries,
49
+ fn: async function ({ descriptorName }, {
50
+ getCwd,
51
+ loadConf,
52
+ readFile,
53
+ writeFile,
54
+ ensureForgeFolder
55
+ }) {
56
+ const cwd = await getCwd()
57
+ const forgeJson = await loadConf({})
58
+
59
+ const taskDescriptor = forgeJson.tasks[descriptorName as keyof typeof forgeJson.tasks]
60
+
61
+ if (taskDescriptor === undefined) {
62
+ throw new Error(`Task "${descriptorName}" is not defined in forge.json`)
63
+ }
64
+
65
+ const filePath = path.join(cwd, taskDescriptor.path)
66
+ const forgePath = await ensureForgeFolder()
67
+ const fingerprintFile = path.join(forgePath, `${descriptorName}.task-fingerprint.json`)
68
+
69
+ console.log(`Analyzing task: ${descriptorName}`)
70
+ console.log(`Task file: ${filePath}`)
71
+
72
+ // Read and analyze the task file using the utility function
73
+ const sourceCode = await readFile(filePath)
74
+ const taskFingerprint = analyzeTaskFile(sourceCode, filePath)
75
+
76
+ if (!taskFingerprint) {
77
+ throw new Error('Could not extract fingerprint from task file: ' + filePath)
78
+ }
79
+
80
+ // Create analysis result - clean output without extra fields
81
+ const analysis: FingerprintAnalysis = {
82
+ taskFingerprint
83
+ }
84
+
85
+ // Write fingerprint to file
86
+ await writeFile(fingerprintFile, JSON.stringify(analysis, null, 2))
87
+
88
+ console.log('Task fingerprint generated successfully')
89
+ console.log(`Input properties: ${Object.keys(taskFingerprint.inputSchema.properties).join(', ')}`)
90
+ console.log(`Boundaries: ${taskFingerprint.boundaries.join(', ')}`)
91
+ console.log(`Fingerprint saved to: ${fingerprintFile}`)
92
+
93
+ return {
94
+ taskName: descriptorName,
95
+ fingerprint: taskFingerprint,
96
+ fingerprintFile,
97
+ analysis: {
98
+ inputSchemaProps: Object.keys(taskFingerprint.inputSchema.properties),
99
+ boundaryCount: taskFingerprint.boundaries.length,
100
+ hasDescription: !!taskFingerprint.description,
101
+ outputType: taskFingerprint.outputType.type
102
+ }
103
+ }
104
+ }
105
+ })
106
+
107
+ fingerprint.setDescription(description)
@@ -0,0 +1,58 @@
1
+ // TASK: list
2
+ // Run this task with:
3
+ // forge task:run task:list
4
+
5
+ import { createTask } from '@forgehive/task'
6
+ import { Schema } from '@forgehive/schema'
7
+
8
+ import { load as loadConf } from '../conf/load'
9
+ import { type ForgeConf } from '../types'
10
+
11
+ const description = 'List all available tasks in the current project'
12
+
13
+ const schema = new Schema({
14
+ // No arguments needed
15
+ })
16
+
17
+ const boundaries = {
18
+ loadConf: loadConf.asBoundary()
19
+ }
20
+
21
+ export const list = createTask({
22
+ schema,
23
+ boundaries,
24
+ fn: async function (argv, { loadConf }) {
25
+ // Load forge configuration
26
+ const forge: ForgeConf = await loadConf({})
27
+
28
+ console.log('Available tasks:')
29
+ console.log('===============================================')
30
+
31
+ const tasks = forge.tasks
32
+ const taskNames = Object.keys(tasks).sort()
33
+
34
+ if (taskNames.length === 0) {
35
+ console.log('No tasks found in forge.json')
36
+ return { taskCount: 0, tasks: [] }
37
+ }
38
+
39
+ // Find the longest task name for alignment
40
+ const maxNameLength = Math.max(...taskNames.map(name => name.length))
41
+
42
+ taskNames.forEach((taskName) => {
43
+ const task = tasks[taskName]
44
+ const paddedName = taskName.padEnd(maxNameLength + 1)
45
+ console.log(`• ${paddedName} - ${task.path}`)
46
+ })
47
+
48
+ console.log('===============================================')
49
+ console.log('Total tasks: ', taskNames.length)
50
+ console.log('===============================================')
51
+
52
+ return {
53
+ taskCount: taskNames.length
54
+ }
55
+ }
56
+ })
57
+
58
+ list.setDescription(description)
@@ -81,10 +81,10 @@ const boundaries = {
81
81
  }
82
82
  }
83
83
 
84
- export const publish = createTask(
84
+ export const publish = createTask({
85
85
  schema,
86
86
  boundaries,
87
- async function ({ descriptorName }, {
87
+ fn: async function ({ descriptorName }, {
88
88
  getCwd,
89
89
  ensureBuildsFolder,
90
90
  loadConf,
@@ -184,4 +184,4 @@ export const publish = createTask(
184
184
  throw new Error('Bundle upload failed')
185
185
  }
186
186
  }
187
- )
187
+ })
@@ -25,10 +25,10 @@ const boundaries = {
25
25
  }
26
26
  }
27
27
 
28
- export const remove = createTask(
28
+ export const remove = createTask({
29
29
  schema,
30
30
  boundaries,
31
- async function ({ descriptorName }, { loadConf, persistConf, deleteFile }) {
31
+ fn: async function ({ descriptorName }, { loadConf, persistConf, deleteFile }) {
32
32
  // Load shadow configuration
33
33
  const forge: ForgeConf = await loadConf({})
34
34
 
@@ -61,4 +61,4 @@ export const remove = createTask(
61
61
  message: `Task '${descriptorName}' has been successfully removed`
62
62
  }
63
63
  }
64
- )
64
+ })
@@ -96,10 +96,10 @@ const boundaries = {
96
96
  }
97
97
  }
98
98
 
99
- export const replay = createTask(
99
+ export const replay = createTask({
100
100
  schema,
101
101
  boundaries,
102
- async function ({ descriptorName, path: fixturePath, cache }, { readFixture, loadConf, loadCurrentProfile, bundleCreate, bundleLoad, ensureBuildsFolder, verifyLogFolder, sendLogToAPI }) {
102
+ fn: async function ({ descriptorName, path: fixturePath, cache }, { readFixture, loadConf, loadCurrentProfile, bundleCreate, bundleLoad, ensureBuildsFolder, verifyLogFolder, sendLogToAPI }) {
103
103
  console.log('Input descriptorName:', descriptorName)
104
104
  console.log('Input path:', fixturePath)
105
105
  console.log('Input cache:', cache)
@@ -215,6 +215,6 @@ export const replay = createTask(
215
215
 
216
216
  return result
217
217
  }
218
- )
218
+ })
219
219
 
220
220
  replay.setDescription(description)
@@ -1,6 +1,7 @@
1
1
  // TASK: run
2
2
  // Run this task with:
3
- // shadow-cli task:run
3
+ // most recursive call on the project
4
+ // forge task:run task:run
4
5
 
5
6
  import path from 'path'
6
7
  import fs from 'fs/promises'
@@ -78,10 +79,10 @@ const boundaries = {
78
79
  }
79
80
  }
80
81
 
81
- export const run = createTask(
82
+ export const run = createTask({
82
83
  schema,
83
84
  boundaries,
84
- async function ({ descriptorName, args }, {
85
+ fn: async function ({ descriptorName, args }, {
85
86
  loadConf,
86
87
  bundleCreate,
87
88
  bundleLoad,
@@ -187,4 +188,4 @@ export const run = createTask(
187
188
 
188
189
  return result
189
190
  }
190
- )
191
+ })
@@ -0,0 +1,14 @@
1
+ // Global test setup - mocks for problematic ES modules
2
+
3
+ // Mock archiver to avoid ES module issues
4
+ jest.mock('archiver', () => ({
5
+ __esModule: true,
6
+ default: jest.fn(() => ({
7
+ pipe: jest.fn(),
8
+ finalize: jest.fn(),
9
+ directory: jest.fn(),
10
+ file: jest.fn(),
11
+ on: jest.fn(),
12
+ pointer: jest.fn(() => 0)
13
+ }))
14
+ }))
@@ -1,5 +1,5 @@
1
1
  import { createTaskCommand } from '../../tasks/task/createTask'
2
- import { createFsFromVolume, Volume } from 'memfs'
2
+ import { createFsFromVolume, Volume, type IFs } from 'memfs'
3
3
  import path from 'path'
4
4
  import { createMockBoundary } from '../testUtils'
5
5
  import { ForgeConf } from '../../tasks/types'
@@ -12,6 +12,7 @@ const expectedContent = `// TASK: newTask
12
12
  import { createTask } from '@forgehive/task'
13
13
  import { Schema } from '@forgehive/schema'
14
14
 
15
+ const name = 'sample:newTask'
15
16
  const description = 'Add task description here'
16
17
 
17
18
  const schema = new Schema({
@@ -24,10 +25,12 @@ const boundaries = {
24
25
  // example: readFile: async (path: string) => fs.readFile(path, 'utf-8')
25
26
  }
26
27
 
27
- export const newTask = createTask(
28
+ export const newTask = createTask({
29
+ name,
30
+ description,
28
31
  schema,
29
32
  boundaries,
30
- async function (argv, boundaries) {
33
+ fn: async function (argv, boundaries) {
31
34
  console.log('input:', argv)
32
35
  console.log('boundaries:', boundaries)
33
36
  // Your task implementation goes here
@@ -35,15 +38,13 @@ export const newTask = createTask(
35
38
 
36
39
  return status
37
40
  }
38
- )
41
+ })
39
42
 
40
- newTask.setDescription(description)
41
43
  `
42
44
 
43
45
  describe('Create task', () => {
44
46
  let volume: InstanceType<typeof Volume>
45
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
- let fs: any
47
+ let fs: IFs
47
48
  let rootDir: string
48
49
 
49
50
  beforeEach(() => {
@@ -96,11 +97,10 @@ describe('Create task', () => {
96
97
 
97
98
  // Read the created task file
98
99
  const fileContent = await fs.promises.readFile(path.join(rootDir, 'src/tasks/sample', 'newTask.ts'), 'utf-8')
99
-
100
100
  expect(fileContent).toBe(expectedContent)
101
101
 
102
102
  // Read the updated forge.json
103
- const forgeContent = await fs.promises.readFile(path.join(rootDir, 'forge.json'), 'utf-8')
103
+ const forgeContent = await fs.promises.readFile(path.join(rootDir, 'forge.json'), 'utf-8') as string
104
104
  const forgeConf = JSON.parse(forgeContent)
105
105
  expect(forgeConf.tasks['sample:newTask']).toBeDefined()
106
106
  })