@forgehive/forge-cli 0.3.13 → 0.3.15

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/dist/runner.js CHANGED
@@ -163,9 +163,10 @@ runner.setHandler(async (data) => {
163
163
  });
164
164
  }
165
165
  else if (taskName === 'docs:download') {
166
- const { path } = args;
166
+ const { path, logs } = args;
167
167
  result = await task.run({
168
- path
168
+ path,
169
+ logs
169
170
  });
170
171
  }
171
172
  else if (taskName === 'project:create') {
@@ -1,5 +1,6 @@
1
1
  export declare const download: import("@forgehive/task").TaskInstanceType<(argv: {
2
2
  path?: string | undefined;
3
+ logs?: boolean | undefined;
3
4
  }, boundaries: import("@forgehive/task").WrappedBoundaries<{
4
5
  fetchFile: (url: string) => Promise<string>;
5
6
  getCurrentWorkingDirectory: () => Promise<string>;
@@ -8,9 +9,13 @@ export declare const download: import("@forgehive/task").TaskInstanceType<(argv:
8
9
  checkFileExists: (filePath: string) => Promise<boolean>;
9
10
  }>) => Promise<{
10
11
  success: boolean;
11
- filePath: string;
12
- targetPath: string;
13
- size: number;
12
+ downloads: {
13
+ type: string;
14
+ filePath: string;
15
+ targetPath: string;
16
+ size: number;
17
+ }[];
18
+ totalFiles: number;
14
19
  }>, {
15
20
  fetchFile: (url: string) => Promise<string>;
16
21
  getCurrentWorkingDirectory: () => Promise<string>;
@@ -3,6 +3,8 @@
3
3
  // Run this task with:
4
4
  // forge task:run docs:download
5
5
  // forge task:run docs:download --path="custom/path/forge.md"
6
+ // forge task:run docs:download --logs
7
+ // forge task:run docs:download --logs --path="custom/path/forge.md"
6
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
9
  if (k2 === undefined) k2 = k;
8
10
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -45,10 +47,12 @@ const task_1 = require("@forgehive/task");
45
47
  const schema_1 = require("@forgehive/schema");
46
48
  const path_1 = __importDefault(require("path"));
47
49
  const name = 'docs:download';
48
- const description = 'Download the ForgeHive LLM guide from GitHub to local project';
50
+ const description = 'Download ForgeHive LLM guides from GitHub to local project';
49
51
  const LLM_GUIDE_URL = 'https://raw.githubusercontent.com/forge-and-hive/forge-mono-repo/refs/heads/main/docs/llm.md';
52
+ const LLM_HIVE_LOGGING_URL = 'https://raw.githubusercontent.com/forge-and-hive/forge-mono-repo/refs/heads/main/docs/llm-hive-logging.md';
50
53
  const schema = new schema_1.Schema({
51
- path: schema_1.Schema.string().optional()
54
+ path: schema_1.Schema.string().optional(),
55
+ logs: schema_1.Schema.boolean().optional()
52
56
  });
53
57
  const boundaries = {
54
58
  fetchFile: async (url) => {
@@ -85,30 +89,63 @@ exports.download = (0, task_1.createTask)({
85
89
  description,
86
90
  schema,
87
91
  boundaries,
88
- fn: async function ({ path: customPath }, { fetchFile, getCurrentWorkingDirectory, createDirectory, writeFile, checkFileExists }) {
89
- // Determine the target path
90
- const targetPath = customPath || 'docs/forge.md';
92
+ fn: async function ({ path: customPath, logs }, { fetchFile, getCurrentWorkingDirectory, createDirectory, writeFile, checkFileExists }) {
91
93
  const cwd = await getCurrentWorkingDirectory();
92
- const fullPath = path_1.default.resolve(cwd, targetPath);
93
- const dirPath = path_1.default.dirname(fullPath);
94
- console.log(`Downloading ForgeHive LLM guide to: ${targetPath}`);
94
+ const results = [];
95
+ // Download main LLM guide
96
+ const mainTargetPath = customPath || 'docs/forge.md';
97
+ const mainFullPath = path_1.default.resolve(cwd, mainTargetPath);
98
+ const mainDirPath = path_1.default.dirname(mainFullPath);
99
+ console.log(`Downloading ForgeHive LLM guide to: ${mainTargetPath}`);
95
100
  // Check if file already exists
96
- const fileExists = await checkFileExists(fullPath);
97
- if (fileExists) {
98
- console.log(`Warning: File already exists at ${targetPath}. It will be overwritten.`);
101
+ const mainFileExists = await checkFileExists(mainFullPath);
102
+ if (mainFileExists) {
103
+ console.log(`Warning: File already exists at ${mainTargetPath}. It will be overwritten.`);
99
104
  }
100
- // Download the file content
101
- const content = await fetchFile(LLM_GUIDE_URL);
105
+ // Download the main guide content
106
+ const mainContent = await fetchFile(LLM_GUIDE_URL);
102
107
  // Create directory if it doesn't exist
103
- await createDirectory(dirPath);
104
- // Write the file
105
- await writeFile(fullPath, content);
106
- console.log(`✅ Successfully downloaded ForgeHive LLM guide to ${targetPath}`);
108
+ await createDirectory(mainDirPath);
109
+ // Write the main guide file
110
+ await writeFile(mainFullPath, mainContent);
111
+ console.log(`✅ Successfully downloaded ForgeHive LLM guide to ${mainTargetPath}`);
112
+ results.push({
113
+ type: 'main',
114
+ filePath: mainFullPath,
115
+ targetPath: mainTargetPath,
116
+ size: mainContent.length
117
+ });
118
+ // Download Hive logging guide if --logs flag is provided
119
+ if (logs) {
120
+ const logsTargetPath = customPath
121
+ ? path_1.default.join(path_1.default.dirname(customPath), 'hive-logging.md')
122
+ : 'docs/hive-logging.md';
123
+ const logsFullPath = path_1.default.resolve(cwd, logsTargetPath);
124
+ const logsDirPath = path_1.default.dirname(logsFullPath);
125
+ console.log(`Downloading Hive Logging guide to: ${logsTargetPath}`);
126
+ // Check if logs file already exists
127
+ const logsFileExists = await checkFileExists(logsFullPath);
128
+ if (logsFileExists) {
129
+ console.log(`Warning: File already exists at ${logsTargetPath}. It will be overwritten.`);
130
+ }
131
+ // Download the logs guide content
132
+ const logsContent = await fetchFile(LLM_HIVE_LOGGING_URL);
133
+ // Create directory if it doesn't exist
134
+ await createDirectory(logsDirPath);
135
+ // Write the logs guide file
136
+ await writeFile(logsFullPath, logsContent);
137
+ console.log(`✅ Successfully downloaded Hive Logging guide to ${logsTargetPath}`);
138
+ results.push({
139
+ type: 'logs',
140
+ filePath: logsFullPath,
141
+ targetPath: logsTargetPath,
142
+ size: logsContent.length
143
+ });
144
+ }
107
145
  return {
108
146
  success: true,
109
- filePath: fullPath,
110
- targetPath,
111
- size: content.length
147
+ downloads: results,
148
+ totalFiles: results.length
112
149
  };
113
150
  }
114
151
  });
@@ -7,10 +7,10 @@ export declare const invoke: import("@forgehive/task").TaskInstanceType<(argv: {
7
7
  loadConf: (args: {}) => Promise<Promise<ForgeConf>>;
8
8
  loadCurrentProfile: (args: {}) => Promise<Promise<Profile>>;
9
9
  parseJSON: (jsonString: string) => Promise<unknown>;
10
- invokeTask: (projectUuid: string, profile: Profile, taskName: string, payload: unknown) => Promise<InvokeResult | null>;
10
+ invokeTask: (projectUuid: string, taskUuid: string, profile: Profile, taskName: string, payload: unknown) => Promise<InvokeResult | null>;
11
11
  }>) => Promise<unknown>, {
12
12
  loadConf: (args: {}) => Promise<Promise<ForgeConf>>;
13
13
  loadCurrentProfile: (args: {}) => Promise<Promise<Profile>>;
14
14
  parseJSON: (jsonString: string) => Promise<unknown>;
15
- invokeTask: (projectUuid: string, profile: Profile, taskName: string, payload: unknown) => Promise<InvokeResult | null>;
15
+ invokeTask: (projectUuid: string, taskUuid: string, profile: Profile, taskName: string, payload: unknown) => Promise<InvokeResult | null>;
16
16
  }>;
@@ -26,17 +26,17 @@ const boundaries = {
26
26
  throw new Error(`Invalid JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
27
27
  }
28
28
  },
29
- invokeTask: async (projectUuid, profile, taskName, payload) => {
29
+ invokeTask: async (projectUuid, taskUuid, profile, taskName, payload) => {
30
30
  const client = (0, hive_sdk_1.createHiveClient)({
31
31
  projectUuid,
32
32
  apiKey: profile.apiKey,
33
33
  apiSecret: profile.apiSecret,
34
34
  host: profile.url
35
35
  });
36
- console.log(`Invoking task: ${taskName}`);
36
+ console.log(`Invoking task: ${taskName} (${taskUuid})`);
37
37
  console.log('Payload:', payload);
38
38
  console.log(`Using profile: ${profile.name} (${profile.url})`);
39
- return await client.invoke(taskName, payload);
39
+ return await client.invoke(taskUuid, payload);
40
40
  }
41
41
  };
42
42
  exports.invoke = (0, task_1.createTask)({
@@ -51,10 +51,13 @@ exports.invoke = (0, task_1.createTask)({
51
51
  if (taskDescriptor === undefined) {
52
52
  throw new Error(`Task "${descriptorName}" is not defined in forge.json`);
53
53
  }
54
- // Check for project UUID
54
+ // Check for required UUIDs
55
55
  if (!forge.project.uuid) {
56
56
  throw new Error('Project UUID is not defined in forge.json. Please ensure your project has a UUID.');
57
57
  }
58
+ if (!taskDescriptor.uuid) {
59
+ throw new Error(`Task "${descriptorName}" does not have a UUID in forge.json. Please ensure your task has a UUID.`);
60
+ }
58
61
  // Load profile (required for invoke)
59
62
  let profile;
60
63
  try {
@@ -66,7 +69,7 @@ exports.invoke = (0, task_1.createTask)({
66
69
  // Parse the JSON payload
67
70
  const payload = await parseJSON(json);
68
71
  // Invoke the task using the boundary
69
- const result = await invokeTask(forge.project.uuid, profile, descriptorName, payload);
72
+ const result = await invokeTask(forge.project.uuid, taskDescriptor.uuid, profile, descriptorName, payload);
70
73
  if ((0, hive_sdk_1.isInvokeError)(result)) {
71
74
  throw new Error(`Task invocation failed: ${result.error}`);
72
75
  }
@@ -47,7 +47,7 @@ export declare const publish: import("@forgehive/task").TaskInstanceType<(argv:
47
47
  }>>;
48
48
  readFileUtf8: (filePath: string) => Promise<string>;
49
49
  readFileBinary: (filePath: string) => Promise<Buffer>;
50
- publishTask: (data: Record<string, unknown>, profile: Profile) => Promise<{
50
+ publishTask: (projectUuid: string, taskUuid: string, data: Record<string, unknown>, profile: Profile) => Promise<{
51
51
  bundleUploadUrl?: string;
52
52
  }>;
53
53
  uploadBundleWithPresignedUrl: (presignedUrl: string, bundleContent: Buffer) => Promise<boolean>;
@@ -101,7 +101,7 @@ export declare const publish: import("@forgehive/task").TaskInstanceType<(argv:
101
101
  }>>;
102
102
  readFileUtf8: (filePath: string) => Promise<string>;
103
103
  readFileBinary: (filePath: string) => Promise<Buffer>;
104
- publishTask: (data: Record<string, unknown>, profile: Profile) => Promise<{
104
+ publishTask: (projectUuid: string, taskUuid: string, data: Record<string, unknown>, profile: Profile) => Promise<{
105
105
  bundleUploadUrl?: string;
106
106
  }>;
107
107
  uploadBundleWithPresignedUrl: (presignedUrl: string, bundleContent: Buffer) => Promise<boolean>;
@@ -38,8 +38,8 @@ const boundaries = {
38
38
  readFileBinary: async (filePath) => {
39
39
  return promises_1.default.readFile(filePath);
40
40
  },
41
- publishTask: async (data, profile) => {
42
- const publishUrl = `${profile.url}/api/tasks/publish`;
41
+ publishTask: async (projectUuid, taskUuid, data, profile) => {
42
+ const publishUrl = `${profile.url}/api/projects/${projectUuid}/tasks/${taskUuid}/publish`;
43
43
  const authToken = `${profile.apiKey}:${profile.apiSecret}`;
44
44
  try {
45
45
  const response = await axios_1.default.post(publishUrl, data, {
@@ -91,6 +91,13 @@ exports.publish = (0, task_1.createTask)({
91
91
  if (taskDescriptor === undefined) {
92
92
  throw new Error('Task is not defined on forge.json');
93
93
  }
94
+ // Check for required UUIDs
95
+ if (!forgeJson.project.uuid) {
96
+ throw new Error('Project UUID is not defined in forge.json. Please ensure your project has a UUID.');
97
+ }
98
+ if (!taskDescriptor.uuid) {
99
+ throw new Error(`Task "${descriptorName}" does not have a UUID in forge.json. Please ensure your task has a UUID.`);
100
+ }
94
101
  const entryPoint = path_1.default.join(cwd, taskDescriptor.path);
95
102
  const buildsPath = await ensureBuildsFolder();
96
103
  const outputFile = path_1.default.join(buildsPath, `${descriptorName}.js`);
@@ -158,7 +165,7 @@ exports.publish = (0, task_1.createTask)({
158
165
  };
159
166
  // Publish metadata to hive api server
160
167
  console.log(`Publishing metadata and source code to ${profile.url}...`);
161
- const publishResponse = await publishTask(data, profile);
168
+ const publishResponse = await publishTask(forgeJson.project.uuid, taskDescriptor.uuid, data, profile);
162
169
  // Upload zipped bundle using the presigned URL
163
170
  if (publishResponse.bundleUploadUrl) {
164
171
  console.log('Uploading zipped bundle...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgehive/forge-cli",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "TypeScript CLI application",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -10,7 +10,7 @@
10
10
  "publishConfig": {
11
11
  "access": "public",
12
12
  "dependencies": {
13
- "@forgehive/hive-sdk": "^0.1.4",
13
+ "@forgehive/hive-sdk": "^0.1.5",
14
14
  "@forgehive/record-tape": "^0.2.6",
15
15
  "@forgehive/runner": "^0.2.6",
16
16
  "@forgehive/schema": "^0.1.4",
@@ -30,11 +30,11 @@
30
30
  "minimist": "^1.2.8",
31
31
  "typescript": "^5.3.3",
32
32
  "uuid": "^11.1.0",
33
- "@forgehive/record-tape": "0.2.6",
34
- "@forgehive/hive-sdk": "0.1.4",
33
+ "@forgehive/schema": "0.1.4",
35
34
  "@forgehive/task": "0.2.6",
36
- "@forgehive/runner": "0.2.6",
37
- "@forgehive/schema": "0.1.4"
35
+ "@forgehive/hive-sdk": "0.1.5",
36
+ "@forgehive/record-tape": "0.2.6",
37
+ "@forgehive/runner": "0.2.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/archiver": "^6.0.3",
package/src/runner.ts CHANGED
@@ -184,10 +184,11 @@ runner.setHandler(async (data: ParsedArgs): Promise<unknown> => {
184
184
  profileName: String(action)
185
185
  })
186
186
  } else if (taskName === 'docs:download') {
187
- const { path } = args as { path?: string }
187
+ const { path, logs } = args as { path?: string, logs?: boolean }
188
188
 
189
189
  result = await task.run({
190
- path
190
+ path,
191
+ logs
191
192
  })
192
193
  } else if (taskName === 'project:create') {
193
194
  const { projectName, description } = args as { projectName?: string, description?: string }
@@ -2,18 +2,22 @@
2
2
  // Run this task with:
3
3
  // forge task:run docs:download
4
4
  // forge task:run docs:download --path="custom/path/forge.md"
5
+ // forge task:run docs:download --logs
6
+ // forge task:run docs:download --logs --path="custom/path/forge.md"
5
7
 
6
8
  import { createTask } from '@forgehive/task'
7
9
  import { Schema } from '@forgehive/schema'
8
10
  import path from 'path'
9
11
 
10
12
  const name = 'docs:download'
11
- const description = 'Download the ForgeHive LLM guide from GitHub to local project'
13
+ const description = 'Download ForgeHive LLM guides from GitHub to local project'
12
14
 
13
15
  const LLM_GUIDE_URL = 'https://raw.githubusercontent.com/forge-and-hive/forge-mono-repo/refs/heads/main/docs/llm.md'
16
+ const LLM_HIVE_LOGGING_URL = 'https://raw.githubusercontent.com/forge-and-hive/forge-mono-repo/refs/heads/main/docs/llm-hive-logging.md'
14
17
 
15
18
  const schema = new Schema({
16
- path: Schema.string().optional()
19
+ path: Schema.string().optional(),
20
+ logs: Schema.boolean().optional()
17
21
  })
18
22
 
19
23
  const boundaries = {
@@ -51,37 +55,80 @@ export const download = createTask({
51
55
  description,
52
56
  schema,
53
57
  boundaries,
54
- fn: async function ({ path: customPath }, { fetchFile, getCurrentWorkingDirectory, createDirectory, writeFile, checkFileExists }) {
55
- // Determine the target path
56
- const targetPath = customPath || 'docs/forge.md'
58
+ fn: async function ({ path: customPath, logs }, { fetchFile, getCurrentWorkingDirectory, createDirectory, writeFile, checkFileExists }) {
57
59
  const cwd = await getCurrentWorkingDirectory()
58
- const fullPath = path.resolve(cwd, targetPath)
59
- const dirPath = path.dirname(fullPath)
60
+ const results = []
60
61
 
61
- console.log(`Downloading ForgeHive LLM guide to: ${targetPath}`)
62
+ // Download main LLM guide
63
+ const mainTargetPath = customPath || 'docs/forge.md'
64
+ const mainFullPath = path.resolve(cwd, mainTargetPath)
65
+ const mainDirPath = path.dirname(mainFullPath)
66
+
67
+ console.log(`Downloading ForgeHive LLM guide to: ${mainTargetPath}`)
62
68
 
63
69
  // Check if file already exists
64
- const fileExists = await checkFileExists(fullPath)
65
- if (fileExists) {
66
- console.log(`Warning: File already exists at ${targetPath}. It will be overwritten.`)
70
+ const mainFileExists = await checkFileExists(mainFullPath)
71
+ if (mainFileExists) {
72
+ console.log(`Warning: File already exists at ${mainTargetPath}. It will be overwritten.`)
67
73
  }
68
74
 
69
- // Download the file content
70
- const content = await fetchFile(LLM_GUIDE_URL)
75
+ // Download the main guide content
76
+ const mainContent = await fetchFile(LLM_GUIDE_URL)
71
77
 
72
78
  // Create directory if it doesn't exist
73
- await createDirectory(dirPath)
79
+ await createDirectory(mainDirPath)
80
+
81
+ // Write the main guide file
82
+ await writeFile(mainFullPath, mainContent)
83
+
84
+ console.log(`✅ Successfully downloaded ForgeHive LLM guide to ${mainTargetPath}`)
85
+
86
+ results.push({
87
+ type: 'main',
88
+ filePath: mainFullPath,
89
+ targetPath: mainTargetPath,
90
+ size: mainContent.length
91
+ })
92
+
93
+ // Download Hive logging guide if --logs flag is provided
94
+ if (logs) {
95
+ const logsTargetPath = customPath
96
+ ? path.join(path.dirname(customPath), 'hive-logging.md')
97
+ : 'docs/hive-logging.md'
98
+ const logsFullPath = path.resolve(cwd, logsTargetPath)
99
+ const logsDirPath = path.dirname(logsFullPath)
100
+
101
+ console.log(`Downloading Hive Logging guide to: ${logsTargetPath}`)
74
102
 
75
- // Write the file
76
- await writeFile(fullPath, content)
103
+ // Check if logs file already exists
104
+ const logsFileExists = await checkFileExists(logsFullPath)
105
+ if (logsFileExists) {
106
+ console.log(`Warning: File already exists at ${logsTargetPath}. It will be overwritten.`)
107
+ }
77
108
 
78
- console.log(`✅ Successfully downloaded ForgeHive LLM guide to ${targetPath}`)
109
+ // Download the logs guide content
110
+ const logsContent = await fetchFile(LLM_HIVE_LOGGING_URL)
111
+
112
+ // Create directory if it doesn't exist
113
+ await createDirectory(logsDirPath)
114
+
115
+ // Write the logs guide file
116
+ await writeFile(logsFullPath, logsContent)
117
+
118
+ console.log(`✅ Successfully downloaded Hive Logging guide to ${logsTargetPath}`)
119
+
120
+ results.push({
121
+ type: 'logs',
122
+ filePath: logsFullPath,
123
+ targetPath: logsTargetPath,
124
+ size: logsContent.length
125
+ })
126
+ }
79
127
 
80
128
  return {
81
129
  success: true,
82
- filePath: fullPath,
83
- targetPath,
84
- size: content.length
130
+ downloads: results,
131
+ totalFiles: results.length
85
132
  }
86
133
  }
87
134
  })
@@ -30,6 +30,7 @@ const boundaries = {
30
30
  },
31
31
  invokeTask: async (
32
32
  projectUuid: string,
33
+ taskUuid: string,
33
34
  profile: Profile,
34
35
  taskName: string,
35
36
  payload: unknown
@@ -41,11 +42,11 @@ const boundaries = {
41
42
  host: profile.url
42
43
  })
43
44
 
44
- console.log(`Invoking task: ${taskName}`)
45
+ console.log(`Invoking task: ${taskName} (${taskUuid})`)
45
46
  console.log('Payload:', payload)
46
47
  console.log(`Using profile: ${profile.name} (${profile.url})`)
47
48
 
48
- return await client.invoke(taskName, payload)
49
+ return await client.invoke(taskUuid, payload)
49
50
  }
50
51
  }
51
52
 
@@ -63,11 +64,15 @@ export const invoke = createTask({
63
64
  throw new Error(`Task "${descriptorName}" is not defined in forge.json`)
64
65
  }
65
66
 
66
- // Check for project UUID
67
+ // Check for required UUIDs
67
68
  if (!forge.project.uuid) {
68
69
  throw new Error('Project UUID is not defined in forge.json. Please ensure your project has a UUID.')
69
70
  }
70
71
 
72
+ if (!taskDescriptor.uuid) {
73
+ throw new Error(`Task "${descriptorName}" does not have a UUID in forge.json. Please ensure your task has a UUID.`)
74
+ }
75
+
71
76
  // Load profile (required for invoke)
72
77
  let profile: Profile
73
78
  try {
@@ -80,7 +85,7 @@ export const invoke = createTask({
80
85
  const payload = await parseJSON(json)
81
86
 
82
87
  // Invoke the task using the boundary
83
- const result = await invokeTask(forge.project.uuid, profile, descriptorName, payload)
88
+ const result = await invokeTask(forge.project.uuid, taskDescriptor.uuid, profile, descriptorName, payload)
84
89
 
85
90
  if (isInvokeError(result)) {
86
91
  throw new Error(`Task invocation failed: ${result.error}`)
@@ -39,8 +39,13 @@ const boundaries = {
39
39
  readFileBinary: async (filePath: string): Promise<Buffer> => {
40
40
  return fs.readFile(filePath)
41
41
  },
42
- publishTask: async (data: Record<string, unknown>, profile: Profile): Promise<{ bundleUploadUrl?: string }> => {
43
- const publishUrl = `${profile.url}/api/tasks/publish`
42
+ publishTask: async (
43
+ projectUuid: string,
44
+ taskUuid: string,
45
+ data: Record<string, unknown>,
46
+ profile: Profile
47
+ ): Promise<{ bundleUploadUrl?: string }> => {
48
+ const publishUrl = `${profile.url}/api/projects/${projectUuid}/tasks/${taskUuid}/publish`
44
49
  const authToken = `${profile.apiKey}:${profile.apiSecret}`
45
50
 
46
51
  try {
@@ -112,6 +117,15 @@ export const publish = createTask({
112
117
  throw new Error('Task is not defined on forge.json')
113
118
  }
114
119
 
120
+ // Check for required UUIDs
121
+ if (!forgeJson.project.uuid) {
122
+ throw new Error('Project UUID is not defined in forge.json. Please ensure your project has a UUID.')
123
+ }
124
+
125
+ if (!taskDescriptor.uuid) {
126
+ throw new Error(`Task "${descriptorName}" does not have a UUID in forge.json. Please ensure your task has a UUID.`)
127
+ }
128
+
115
129
  const entryPoint = path.join(cwd, taskDescriptor.path)
116
130
  const buildsPath = await ensureBuildsFolder()
117
131
  const outputFile = path.join(buildsPath, `${descriptorName}.js`)
@@ -190,7 +204,7 @@ export const publish = createTask({
190
204
 
191
205
  // Publish metadata to hive api server
192
206
  console.log(`Publishing metadata and source code to ${profile.url}...`)
193
- const publishResponse = await publishTask(data, profile)
207
+ const publishResponse = await publishTask(forgeJson.project.uuid, taskDescriptor.uuid, data, profile)
194
208
 
195
209
  // Upload zipped bundle using the presigned URL
196
210
  if (publishResponse.bundleUploadUrl) {