maistro 1.2.14 → 1.2.17

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/app.d.ts CHANGED
@@ -69,6 +69,11 @@ export declare class MaistroApp {
69
69
  * Uses full-screen approach for each step
70
70
  */
71
71
  private handleDiscovery;
72
+ /**
73
+ * Prompt user for each required secret one at a time.
74
+ * Returns a map of envVar -> value for secrets the user provided, or null if cancelled.
75
+ */
76
+ private promptForSecrets;
72
77
  /**
73
78
  * Handle discovery phase for planning requests (no skip option)
74
79
  * This is used when the user submits a planning request to refine the plan.
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAkOA,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,cAAc,CAA+B;gBAEzC,WAAW,GAAE,MAAY;IAsBrC,OAAO,CAAC,eAAe;IASvB;;;OAGG;YACW,qBAAqB;IA+CnC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkH5B;;;OAGG;YACW,iBAAiB;IAiE/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACG,YAAY,CAAC,SAAS,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqFtD;;;OAGG;YACW,iBAAiB;IAwD/B;;OAEG;YACW,sBAAsB;IAsCpC;;;OAGG;YACW,iBAAiB;IAoB/B;;;OAGG;YACW,oBAAoB;IAkClC;;OAEG;YACW,qBAAqB;IA4BnC;;OAEG;YACW,gBAAgB;IAoB9B;;;OAGG;YACW,qBAAqB;IAoEnC;;;OAGG;YACW,eAAe;IA0H7B;;;OAGG;YACW,uBAAuB;IAyErC;;OAEG;YACW,4BAA4B;IAkE1C;;OAEG;YACW,oBAAoB;IAiElC;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,UAAU;IAQlB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IA2J7B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;OAGG;YACW,YAAY;IAyT1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;YACW,aAAa;IAsmB3B;;;OAGG;YACW,iBAAiB;IAgI/B;;OAEG;YACW,cAAc;IAwU5B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;YACW,gBAAgB;IAkB9B;;OAEG;YACW,gBAAgB;IAe9B;;;OAGG;YACW,WAAW;IAsEzB;;;OAGG;YACW,mBAAmB;IA8BjC;;;OAGG;YACW,cAAc;IAkB5B;;;;OAIG;YACW,6BAA6B;IAqI3C;;;OAGG;YACW,aAAa;IA+B3B;;;;OAIG;YACW,sBAAsB;IA8MpC;;;;OAIG;YACW,sBAAsB;YA2GtB,UAAU;IA8HxB,OAAO,CAAC,YAAY;IAmFpB;;;OAGG;YACW,eAAe;IAqD7B;;OAEG;YACW,cAAc;IAsO5B;;OAEG;YACW,oBAAoB;IAwBlC;;OAEG;YACW,eAAe;IAU7B;;OAEG;YACW,wBAAwB;YAsBxB,gBAAgB;IA4B9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsD;IAEpF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAQ/B;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;YAoEhB,SAAS;YAiIT,sBAAsB;CAkcrC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAmOA,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,cAAc,CAA+B;gBAEzC,WAAW,GAAE,MAAY;IAsBrC,OAAO,CAAC,eAAe;IASvB;;;OAGG;YACW,qBAAqB;IA+CnC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkH5B;;;OAGG;YACW,iBAAiB;IAiE/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACG,YAAY,CAAC,SAAS,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqFtD;;;OAGG;YACW,iBAAiB;IAwD/B;;OAEG;YACW,sBAAsB;IAsCpC;;;OAGG;YACW,iBAAiB;IAoB/B;;;OAGG;YACW,oBAAoB;IAkClC;;OAEG;YACW,qBAAqB;IA4BnC;;OAEG;YACW,gBAAgB;IAoB9B;;;OAGG;YACW,qBAAqB;IAoEnC;;;OAGG;YACW,eAAe;IAwJ7B;;;OAGG;YACW,gBAAgB;IAiD9B;;;OAGG;YACW,uBAAuB;IAyErC;;OAEG;YACW,4BAA4B;IAkE1C;;OAEG;YACW,oBAAoB;IAiElC;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,UAAU;IAQlB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IA2J7B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;OAGG;YACW,YAAY;IAyT1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;YACW,aAAa;IAsmB3B;;;OAGG;YACW,iBAAiB;IAgI/B;;OAEG;YACW,cAAc;IAwU5B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;YACW,gBAAgB;IAkB9B;;OAEG;YACW,gBAAgB;IAe9B;;;OAGG;YACW,WAAW;IAsEzB;;;OAGG;YACW,mBAAmB;IA8BjC;;;OAGG;YACW,cAAc;IAkB5B;;;;OAIG;YACW,6BAA6B;IAqI3C;;;OAGG;YACW,aAAa;IA+B3B;;;;OAIG;YACW,sBAAsB;IA8MpC;;;;OAIG;YACW,sBAAsB;YA2GtB,UAAU;IA8HxB,OAAO,CAAC,YAAY;IAmFpB;;;OAGG;YACW,eAAe;IAqD7B;;OAEG;YACW,cAAc;IAsO5B;;OAEG;YACW,oBAAoB;IAwBlC;;OAEG;YACW,eAAe;IAU7B;;OAEG;YACW,wBAAwB;YAsBxB,gBAAgB;IA4B9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsD;IAEpF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAQ/B;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;YAoEhB,SAAS;YAiIT,sBAAsB;CAkcrC"}
package/dist/app.js CHANGED
@@ -6,6 +6,7 @@ import { exec } from 'node:child_process';
6
6
  import { Orchestrator } from './orchestrator.js';
7
7
  import { InteractiveUI, ExitRequestedError, formatTaskStatus, formatTaskStatusIcon, formatStatusName, formatBlockedStatus, progressBar } from './ui.js';
8
8
  import { planTasks, generateReadme, discoverRequirements, buildProjectContext, formatContextForDecomposition } from './planner.js';
9
+ import { readExistingEnvVars, writeSecretsToEnvFile } from './envFile.js';
9
10
  import { isTaskBlocked } from './taskQueue.js';
10
11
  import { isClaudeCodeInstalled, isClaudeCodeAuthenticated, testClaudeInteraction, launchClaudeLogin, loadConfig, saveConfig, } from './config.js';
11
12
  import { initLogger, getLogger } from './logger.js';
@@ -768,6 +769,16 @@ export class MaistroApp {
768
769
  answers[question.id] = answer;
769
770
  getLogger()?.info('Discovery answer', { questionId: question.id, question: question.question, answer });
770
771
  }
772
+ // Prompt for required secrets if any were detected
773
+ const collectedSecrets = {};
774
+ if (result.requiredSecrets && result.requiredSecrets.length > 0) {
775
+ const secretResults = await this.promptForSecrets(result.requiredSecrets);
776
+ if (secretResults === null) {
777
+ // User cancelled
778
+ return null;
779
+ }
780
+ Object.assign(collectedSecrets, secretResults);
781
+ }
771
782
  // Show confirmation screen (full-screen)
772
783
  this.ui.clear();
773
784
  this.showHeader();
@@ -779,6 +790,19 @@ export class MaistroApp {
779
790
  const label = question ? question.id.replace(/-/g, ' ').replace(/^\w/, c => c.toUpperCase()) : id;
780
791
  console.log(` \x1b[36m${label}:\x1b[0m ${value}`);
781
792
  }
793
+ // Show secrets status summary
794
+ if (result.requiredSecrets && result.requiredSecrets.length > 0) {
795
+ console.log('\n\x1b[90mSecrets/Credentials:\x1b[0m');
796
+ for (const secret of result.requiredSecrets) {
797
+ const provided = collectedSecrets[secret.envVar];
798
+ if (provided) {
799
+ console.log(` \x1b[32m✓\x1b[0m \x1b[33m${secret.envVar}\x1b[0m — provided`);
800
+ }
801
+ else {
802
+ console.log(` \x1b[90m○\x1b[0m \x1b[33m${secret.envVar}\x1b[0m — skipped`);
803
+ }
804
+ }
805
+ }
782
806
  console.log('');
783
807
  const confirmChoice = await this.ui.quickPick([
784
808
  { key: 'y', label: 'Continue', description: 'Create plan with these preferences' },
@@ -793,15 +817,66 @@ export class MaistroApp {
793
817
  if (confirmChoice === null) {
794
818
  return null;
795
819
  }
796
- getLogger()?.info('Discovery completed', { summary: result.summary, answers });
820
+ // Write collected secrets to .env.local
821
+ if (Object.keys(collectedSecrets).length > 0) {
822
+ writeSecretsToEnvFile(this.projectPath, collectedSecrets);
823
+ }
824
+ getLogger()?.info('Discovery completed', { summary: result.summary, answers, requiredSecrets: result.requiredSecrets, secretsProvided: Object.keys(collectedSecrets) });
797
825
  return {
798
826
  summary: result.summary,
799
827
  questions: result.questions,
800
828
  assumptions: result.assumptions,
801
829
  answers,
802
830
  confirmed: true,
831
+ requiredSecrets: result.requiredSecrets,
803
832
  };
804
833
  }
834
+ /**
835
+ * Prompt user for each required secret one at a time.
836
+ * Returns a map of envVar -> value for secrets the user provided, or null if cancelled.
837
+ */
838
+ async promptForSecrets(secrets) {
839
+ const collected = {};
840
+ // Check which secrets already exist in .env or .env.local
841
+ const existing = readExistingEnvVars(this.projectPath);
842
+ for (let i = 0; i < secrets.length; i++) {
843
+ const secret = secrets[i];
844
+ const existingValue = existing[secret.envVar];
845
+ const progressText = `Secret ${i + 1} of ${secrets.length}`;
846
+ if (existingValue) {
847
+ // Already present - show and let user confirm or update
848
+ const choice = await this.fullScreenMenu({
849
+ title: progressText,
850
+ subtitle: `\x1b[33m${secret.envVar}\x1b[0m — ${secret.name} (${secret.service})\n\nAlready set in .env file: ${existingValue.slice(0, 8)}${'*'.repeat(Math.max(0, existingValue.length - 8))}`,
851
+ items: [
852
+ { key: 'k', label: 'Keep', description: 'Keep existing value' },
853
+ { key: 'u', label: 'Update', description: 'Enter a new value' },
854
+ ],
855
+ exitOnDoubleEscape: true,
856
+ });
857
+ if (choice === null)
858
+ return null;
859
+ if (choice === 'k')
860
+ continue;
861
+ // Fall through to prompt for new value
862
+ }
863
+ const phaseLabel = secret.phase === 'both' ? 'build + runtime' : secret.phase;
864
+ const subtitle = `\x1b[33m${secret.envVar}\x1b[0m — ${secret.name} (${secret.service})\n\n\x1b[90mObtain from:\x1b[0m ${secret.obtainFrom}\n\x1b[90mNeeded at:\x1b[0m ${phaseLabel}`;
865
+ const value = await this.fullScreenTextInput({
866
+ title: progressText,
867
+ subtitle,
868
+ placeholder: 'paste your secret value... (Enter to skip)',
869
+ hint: 'Enter to continue, Esc to cancel setup',
870
+ exitOnDoubleEscape: true,
871
+ });
872
+ if (value === null)
873
+ return null; // User cancelled
874
+ if (value.trim()) {
875
+ collected[secret.envVar] = value.trim();
876
+ }
877
+ }
878
+ return collected;
879
+ }
805
880
  /**
806
881
  * Handle discovery phase for planning requests (no skip option)
807
882
  * This is used when the user submits a planning request to refine the plan.