@gxp-dev/tools 2.0.28 → 2.0.30

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.
@@ -262,6 +262,7 @@ async function generateWithClaude(userPrompt, projectName, description) {
262
262
 
263
263
  return new Promise((resolve) => {
264
264
  console.log("\nšŸ¤– Generating plugin scaffold with Claude...\n");
265
+ console.log("─".repeat(50));
265
266
 
266
267
  let output = "";
267
268
  let errorOutput = "";
@@ -277,30 +278,47 @@ async function generateWithClaude(userPrompt, projectName, description) {
277
278
  );
278
279
 
279
280
  claude.stdout.on("data", (data) => {
280
- output += data.toString();
281
+ const chunk = data.toString();
282
+ output += chunk;
283
+ // Stream output to user in real-time
284
+ process.stdout.write(chunk);
281
285
  });
282
286
 
283
287
  claude.stderr.on("data", (data) => {
284
- errorOutput += data.toString();
288
+ const chunk = data.toString();
289
+ errorOutput += chunk;
290
+ // Show stderr as well (may contain progress info)
291
+ process.stderr.write(chunk);
285
292
  });
286
293
 
287
294
  claude.on("close", (code) => {
295
+ console.log("\n" + "─".repeat(50));
296
+
288
297
  if (code !== 0) {
289
- console.error(`āŒ Claude CLI error: ${errorOutput}`);
298
+ console.error(`\nāŒ Claude CLI error (exit code ${code})`);
299
+ if (errorOutput) {
300
+ console.error(errorOutput);
301
+ }
302
+ resolve(null);
303
+ return;
304
+ }
305
+
306
+ if (!output.trim()) {
307
+ console.error("āŒ No response received from Claude");
290
308
  resolve(null);
291
309
  return;
292
310
  }
293
311
 
294
312
  const scaffoldData = parseAIResponse(output);
295
313
  if (!scaffoldData) {
296
- console.error("āŒ Could not parse Claude response");
297
- console.log("Raw response:", output.slice(0, 500));
314
+ console.error("\nāŒ Could not parse Claude response as JSON");
315
+ console.log("The AI response was shown above but couldn't be parsed into scaffold data.");
298
316
  resolve(null);
299
317
  return;
300
318
  }
301
319
 
302
320
  if (scaffoldData.explanation) {
303
- console.log("šŸ“ AI Explanation:");
321
+ console.log("\nšŸ“ AI Explanation:");
304
322
  console.log(` ${scaffoldData.explanation}`);
305
323
  console.log("");
306
324
  }
@@ -327,6 +345,7 @@ async function generateWithCodex(userPrompt, projectName, description) {
327
345
 
328
346
  return new Promise((resolve) => {
329
347
  console.log("\nšŸ¤– Generating plugin scaffold with Codex...\n");
348
+ console.log("─".repeat(50));
330
349
 
331
350
  let output = "";
332
351
  let errorOutput = "";
@@ -342,30 +361,47 @@ async function generateWithCodex(userPrompt, projectName, description) {
342
361
  );
343
362
 
344
363
  codex.stdout.on("data", (data) => {
345
- output += data.toString();
364
+ const chunk = data.toString();
365
+ output += chunk;
366
+ // Stream output to user in real-time
367
+ process.stdout.write(chunk);
346
368
  });
347
369
 
348
370
  codex.stderr.on("data", (data) => {
349
- errorOutput += data.toString();
371
+ const chunk = data.toString();
372
+ errorOutput += chunk;
373
+ // Show stderr as well
374
+ process.stderr.write(chunk);
350
375
  });
351
376
 
352
377
  codex.on("close", (code) => {
378
+ console.log("\n" + "─".repeat(50));
379
+
353
380
  if (code !== 0) {
354
- console.error(`āŒ Codex CLI error: ${errorOutput}`);
381
+ console.error(`\nāŒ Codex CLI error (exit code ${code})`);
382
+ if (errorOutput) {
383
+ console.error(errorOutput);
384
+ }
385
+ resolve(null);
386
+ return;
387
+ }
388
+
389
+ if (!output.trim()) {
390
+ console.error("āŒ No response received from Codex");
355
391
  resolve(null);
356
392
  return;
357
393
  }
358
394
 
359
395
  const scaffoldData = parseAIResponse(output);
360
396
  if (!scaffoldData) {
361
- console.error("āŒ Could not parse Codex response");
362
- console.log("Raw response:", output.slice(0, 500));
397
+ console.error("\nāŒ Could not parse Codex response as JSON");
398
+ console.log("The AI response was shown above but couldn't be parsed into scaffold data.");
363
399
  resolve(null);
364
400
  return;
365
401
  }
366
402
 
367
403
  if (scaffoldData.explanation) {
368
- console.log("šŸ“ AI Explanation:");
404
+ console.log("\nšŸ“ AI Explanation:");
369
405
  console.log(` ${scaffoldData.explanation}`);
370
406
  console.log("");
371
407
  }
@@ -415,6 +451,7 @@ async function generateWithGemini(
415
451
  async function generateWithGeminiCli(fullPrompt) {
416
452
  return new Promise((resolve) => {
417
453
  console.log("\nšŸ¤– Generating plugin scaffold with Gemini CLI...\n");
454
+ console.log("─".repeat(50));
418
455
 
419
456
  let output = "";
420
457
  let errorOutput = "";
@@ -430,30 +467,47 @@ async function generateWithGeminiCli(fullPrompt) {
430
467
  );
431
468
 
432
469
  gemini.stdout.on("data", (data) => {
433
- output += data.toString();
470
+ const chunk = data.toString();
471
+ output += chunk;
472
+ // Stream output to user in real-time
473
+ process.stdout.write(chunk);
434
474
  });
435
475
 
436
476
  gemini.stderr.on("data", (data) => {
437
- errorOutput += data.toString();
477
+ const chunk = data.toString();
478
+ errorOutput += chunk;
479
+ // Show stderr as well
480
+ process.stderr.write(chunk);
438
481
  });
439
482
 
440
483
  gemini.on("close", (code) => {
484
+ console.log("\n" + "─".repeat(50));
485
+
441
486
  if (code !== 0) {
442
- console.error(`āŒ Gemini CLI error: ${errorOutput}`);
487
+ console.error(`\nāŒ Gemini CLI error (exit code ${code})`);
488
+ if (errorOutput) {
489
+ console.error(errorOutput);
490
+ }
491
+ resolve(null);
492
+ return;
493
+ }
494
+
495
+ if (!output.trim()) {
496
+ console.error("āŒ No response received from Gemini CLI");
443
497
  resolve(null);
444
498
  return;
445
499
  }
446
500
 
447
501
  const scaffoldData = parseAIResponse(output);
448
502
  if (!scaffoldData) {
449
- console.error("āŒ Could not parse Gemini response");
450
- console.log("Raw response:", output.slice(0, 500));
503
+ console.error("\nāŒ Could not parse Gemini response as JSON");
504
+ console.log("The AI response was shown above but couldn't be parsed into scaffold data.");
451
505
  resolve(null);
452
506
  return;
453
507
  }
454
508
 
455
509
  if (scaffoldData.explanation) {
456
- console.log("šŸ“ AI Explanation:");
510
+ console.log("\nšŸ“ AI Explanation:");
457
511
  console.log(` ${scaffoldData.explanation}`);
458
512
  console.log("");
459
513
  }
@@ -474,6 +528,8 @@ async function generateWithGeminiCli(fullPrompt) {
474
528
  async function generateWithGeminiApiKey(fullPrompt, apiKey) {
475
529
  try {
476
530
  console.log("\nšŸ¤– Generating plugin scaffold with Gemini API...\n");
531
+ console.log("─".repeat(50));
532
+ console.log("Sending request to Gemini API...");
477
533
 
478
534
  const response = await fetch(
479
535
  `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`,
@@ -499,8 +555,9 @@ async function generateWithGeminiApiKey(fullPrompt, apiKey) {
499
555
 
500
556
  if (!response.ok) {
501
557
  const errorText = await response.text();
502
- console.error(`āŒ Gemini API error: ${response.status}`);
558
+ console.error(`\nāŒ Gemini API error: ${response.status}`);
503
559
  console.error(errorText);
560
+ console.log("─".repeat(50));
504
561
  return null;
505
562
  }
506
563
 
@@ -509,19 +566,25 @@ async function generateWithGeminiApiKey(fullPrompt, apiKey) {
509
566
 
510
567
  if (!responseText) {
511
568
  console.error("āŒ No response from Gemini API");
569
+ console.log("─".repeat(50));
512
570
  return null;
513
571
  }
514
572
 
573
+ // Show the response to user
574
+ console.log("\nGemini Response:\n");
575
+ console.log(responseText);
576
+ console.log("\n" + "─".repeat(50));
577
+
515
578
  const scaffoldData = parseAIResponse(responseText);
516
579
 
517
580
  if (!scaffoldData) {
518
- console.error("āŒ Could not parse AI response");
519
- console.log("Raw response:", responseText.slice(0, 500));
581
+ console.error("\nāŒ Could not parse Gemini response as JSON");
582
+ console.log("The AI response was shown above but couldn't be parsed into scaffold data.");
520
583
  return null;
521
584
  }
522
585
 
523
586
  if (scaffoldData.explanation) {
524
- console.log("šŸ“ AI Explanation:");
587
+ console.log("\nšŸ“ AI Explanation:");
525
588
  console.log(` ${scaffoldData.explanation}`);
526
589
  console.log("");
527
590
  }
@@ -538,13 +601,13 @@ async function generateWithGeminiApiKey(fullPrompt, apiKey) {
538
601
  */
539
602
  async function generateWithGeminiGcloud(fullPrompt) {
540
603
  return new Promise((resolve) => {
541
- console.log(
542
- "\nšŸ¤– Generating plugin scaffold with Gemini (via gcloud)...\n"
543
- );
604
+ console.log("\nšŸ¤– Generating plugin scaffold with Gemini (via gcloud)...\n");
605
+ console.log("─".repeat(50));
544
606
 
545
607
  // Get access token from gcloud
546
608
  let accessToken;
547
609
  try {
610
+ console.log("Getting gcloud access token...");
548
611
  accessToken = execSync("gcloud auth print-access-token", {
549
612
  stdio: "pipe",
550
613
  })
@@ -552,6 +615,7 @@ async function generateWithGeminiGcloud(fullPrompt) {
552
615
  .trim();
553
616
  } catch (error) {
554
617
  console.error("āŒ Failed to get gcloud access token");
618
+ console.log("─".repeat(50));
555
619
  resolve(null);
556
620
  return;
557
621
  }
@@ -564,12 +628,16 @@ async function generateWithGeminiGcloud(fullPrompt) {
564
628
  })
565
629
  .toString()
566
630
  .trim();
631
+ console.log(`Using project: ${projectId}`);
567
632
  } catch (error) {
568
633
  console.error("āŒ Failed to get gcloud project ID");
634
+ console.log("─".repeat(50));
569
635
  resolve(null);
570
636
  return;
571
637
  }
572
638
 
639
+ console.log("Sending request to Gemini...\n");
640
+
573
641
  const requestBody = JSON.stringify({
574
642
  contents: [
575
643
  {
@@ -615,6 +683,7 @@ async function generateWithGeminiGcloud(fullPrompt) {
615
683
  curl.on("close", (code) => {
616
684
  if (code !== 0) {
617
685
  console.error(`āŒ Gemini gcloud error: ${errorOutput}`);
686
+ console.log("─".repeat(50));
618
687
  resolve(null);
619
688
  return;
620
689
  }
@@ -626,21 +695,27 @@ async function generateWithGeminiGcloud(fullPrompt) {
626
695
 
627
696
  if (!responseText) {
628
697
  console.error("āŒ No response from Gemini");
698
+ console.log("─".repeat(50));
629
699
  resolve(null);
630
700
  return;
631
701
  }
632
702
 
703
+ // Show the response to user
704
+ console.log("Gemini Response:\n");
705
+ console.log(responseText);
706
+ console.log("\n" + "─".repeat(50));
707
+
633
708
  const scaffoldData = parseAIResponse(responseText);
634
709
 
635
710
  if (!scaffoldData) {
636
- console.error("āŒ Could not parse AI response");
637
- console.log("Raw response:", responseText.slice(0, 500));
711
+ console.error("\nāŒ Could not parse Gemini response as JSON");
712
+ console.log("The AI response was shown above but couldn't be parsed into scaffold data.");
638
713
  resolve(null);
639
714
  return;
640
715
  }
641
716
 
642
717
  if (scaffoldData.explanation) {
643
- console.log("šŸ“ AI Explanation:");
718
+ console.log("\nšŸ“ AI Explanation:");
644
719
  console.log(` ${scaffoldData.explanation}`);
645
720
  console.log("");
646
721
  }
@@ -650,6 +725,7 @@ async function generateWithGeminiGcloud(fullPrompt) {
650
725
  console.error(
651
726
  `āŒ Failed to parse Gemini response: ${parseError.message}`
652
727
  );
728
+ console.log("─".repeat(50));
653
729
  resolve(null);
654
730
  }
655
731
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gxp-dev/tools",
3
- "version": "2.0.28",
3
+ "version": "2.0.30",
4
4
  "description": "Dev tools to create platform plugins",
5
5
  "type": "commonjs",
6
6
  "publishConfig": {
@@ -304,17 +304,41 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
304
304
  Object.keys(dependency.operations).length > 0
305
305
  ) {
306
306
  Object.keys(dependency.operations).forEach((operation) => {
307
- let method = "get";
308
- let path = dependency.operations[operation];
309
- if (path.includes(":")) {
310
- let pathSplit = path.split(":");
311
- method = pathSplit[0];
312
- path = pathSplit[1];
307
+ if (
308
+ Object.keys(apiOperations.value[dependency.identifier]).every(
309
+ (key) =>
310
+ [
311
+ "identifier",
312
+ "model",
313
+ "permissionKey",
314
+ "operations",
315
+ ].includes(key)
316
+ )
317
+ ) {
318
+ let method = "get";
319
+ let path = dependency.operations[operation];
320
+ if (path.includes(":")) {
321
+ let pathSplit = path.split(":");
322
+ method = pathSplit[0];
323
+ path = pathSplit[1];
324
+ }
325
+ path = path.replace(
326
+ "{teamSlug}/{projectSlug}",
327
+ pluginVars.value.projectId
328
+ );
329
+ path = path.replace(
330
+ `{${dependency.permissionKey}}`,
331
+ dependencyList.value[dependency.identifier]
332
+ );
333
+ if (!apiOperations.value[dependency.identifier]) {
334
+ apiOperations.value[dependency.identifier] = {};
335
+ }
336
+ apiOperations.value[dependency.identifier][operation] = {
337
+ method: method,
338
+ path: path,
339
+ model_key: dependency.permissionKey,
340
+ };
313
341
  }
314
- apiOperations.value[operation] = {
315
- method: method,
316
- path: path,
317
- };
318
342
  });
319
343
  }
320
344
  if (dependency.events && Object.keys(dependency.events).length > 0) {
@@ -397,8 +421,14 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
397
421
  }
398
422
  async function callApi(operation, identifier, data = {}) {
399
423
  try {
400
- const operation = apiOperations.value[operation];
401
- const response = await apiClient[operation.method](operation.path, data);
424
+ const operationConfig = apiOperations.value[identifier][operation];
425
+ if (!operationConfig) {
426
+ throw new Error(`Operation not found: ${operation}`);
427
+ }
428
+ const response = await apiClient[operationConfig.method](
429
+ operationConfig.path,
430
+ data
431
+ );
402
432
  return response.data;
403
433
  } catch (error) {
404
434
  throw new Error(`${method} ${endpoint}: ${error.message}`);
@@ -8,27 +8,13 @@
8
8
  "appInstructionsFile": "app-instructions.md",
9
9
  "defaultStylingFile": "default-styling.css",
10
10
  "settings": {
11
- "primary_color": "#FFD600",
12
- "background_color": "#ffffff",
13
- "text_color": "#333333",
14
- "start_background_color": "#000596",
15
- "start_text_color": "#FFFFFF",
16
- "final_background_color": "#4CAF50",
17
- "final_text_color": "#ffffff"
11
+ "primary_color": "#FFD600"
18
12
  },
19
13
  "strings": {
20
14
  "default": {
21
- "welcome_text": "Hello World",
22
- "loading_text": "Loading...",
23
- "error_title": "Oops!",
24
- "error_message": "Something went wrong. Please try again.",
25
- "continue_button": "Continue",
26
- "back_button": "Back"
27
15
  }
28
16
  },
29
17
  "assets": {
30
- "main_logo": "/dev-assets/images/logo-placeholder.png",
31
- "background_image": "/dev-assets/images/background-placeholder.jpg"
32
18
  },
33
19
  "dependencies": [],
34
20
  "permissions": []