maistro 1.2.6 → 1.2.8

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAiOA,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;IAoH5B;;;OAGG;YACW,iBAAiB;IAiE/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4C1B;;;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;IAyH7B;;;OAGG;YACW,uBAAuB;IAyErC;;OAEG;YACW,4BAA4B;IAiE1C;;OAEG;YACW,oBAAoB;IAgElC;;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;IAqT1B;;;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;IA4PpC;;;;OAIG;YACW,sBAAsB;YA0GtB,UAAU;IA4HxB,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;IAoB3B;;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":"AAiOA,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;IAoH5B;;;OAGG;YACW,iBAAiB;IAiE/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyC1B;;;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;IAyH7B;;;OAGG;YACW,uBAAuB;IAyErC;;OAEG;YACW,4BAA4B;IAiE1C;;OAEG;YACW,oBAAoB;IAgElC;;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;IAqT1B;;;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;IA6MpC;;;;OAIG;YACW,sBAAsB;YA0GtB,UAAU;IA4HxB,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;IAoB3B;;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
@@ -388,11 +388,12 @@ export class MaistroApp {
388
388
  this.ui.close();
389
389
  // Get the original command arguments (skip node and script path)
390
390
  const args = process.argv.slice(2);
391
- // Spawn new maistro process in detached mode so it becomes the session leader
392
- // This ensures proper terminal control handoff
391
+ // Spawn new maistro process (NOT detached) with inherited stdio.
392
+ // The parent stays alive but idle - the shell waits for the parent,
393
+ // while the child takes over the terminal. This prevents the shell
394
+ // and child from competing for stdin (which happens with detached mode).
393
395
  const child = spawn(process.argv[0], [process.argv[1], ...args], {
394
396
  stdio: 'inherit',
395
- detached: true,
396
397
  env: {
397
398
  ...process.env,
398
399
  // Skip update check on restart to avoid infinite loop
@@ -401,14 +402,11 @@ export class MaistroApp {
401
402
  MAISTRO_IS_RESTART: '1',
402
403
  },
403
404
  });
404
- // Unreference the child so parent can exit independently
405
- child.unref();
406
- // Exit immediately - the detached child will take over
407
- // Using setImmediate to ensure the spawn completes first
408
- setImmediate(() => {
409
- process.exit(0);
405
+ // When child exits, parent exits with the same code
406
+ child.on('exit', (code) => {
407
+ process.exit(code ?? 0);
410
408
  });
411
- // If spawn fails before we exit, show error
409
+ // If spawn fails, show error
412
410
  child.on('error', (err) => {
413
411
  console.error(`\x1b[31m✗ Failed to restart: ${err.message}\x1b[0m`);
414
412
  console.log(`\x1b[90mPlease restart maistro manually.\x1b[0m\n`);
@@ -2772,8 +2770,6 @@ export class MaistroApp {
2772
2770
  this.showHeader();
2773
2771
  console.log(`\x1b[1m── Discussion ──\x1b[0m\n\x1b[90mYou: ${userInput.length > 100 ? userInput.slice(0, 97) + '...' : userInput}\x1b[0m\n`);
2774
2772
  let hasOutput = false;
2775
- let inJsonBlock = false;
2776
- let jsonBlockBuffer = '';
2777
2773
  // Set up abort controller for cancellation
2778
2774
  const abortController = new AbortController();
2779
2775
  let escPendingCancel = false;
@@ -2837,62 +2833,11 @@ export class MaistroApp {
2837
2833
  conversationHistory: [],
2838
2834
  cwd: this.projectPath,
2839
2835
  abortSignal: abortController.signal,
2840
- onOutput: (text) => {
2841
- if (!hasOutput) {
2842
- currentSpinner?.stop(); // Stop spinner on first output
2843
- hasOutput = true;
2844
- }
2845
- // Filter out JSON code blocks from display (they contain task data)
2846
- // We need to handle streaming where text comes in chunks
2847
- let remaining = text;
2848
- while (remaining.length > 0) {
2849
- if (inJsonBlock) {
2850
- // Look for end of JSON block
2851
- const endIndex = remaining.indexOf('```');
2852
- if (endIndex !== -1) {
2853
- // Found end of JSON block
2854
- jsonBlockBuffer += remaining.slice(0, endIndex);
2855
- remaining = remaining.slice(endIndex + 3);
2856
- inJsonBlock = false;
2857
- // Don't output the JSON block content
2858
- }
2859
- else {
2860
- // Still in JSON block, buffer it
2861
- jsonBlockBuffer += remaining;
2862
- remaining = '';
2863
- }
2864
- }
2865
- else {
2866
- // Look for start of JSON block
2867
- const jsonStartIndex = remaining.indexOf('```json');
2868
- if (jsonStartIndex !== -1) {
2869
- // Output text before JSON block
2870
- const beforeJson = remaining.slice(0, jsonStartIndex);
2871
- if (beforeJson) {
2872
- process.stdout.write(beforeJson);
2873
- }
2874
- remaining = remaining.slice(jsonStartIndex + 7); // Skip ```json
2875
- inJsonBlock = true;
2876
- jsonBlockBuffer = '';
2877
- }
2878
- else {
2879
- // No JSON block, check for partial match at end
2880
- const partialMatch = remaining.endsWith('`') || remaining.endsWith('``') || remaining.endsWith('```') || remaining.endsWith('```j') || remaining.endsWith('```js') || remaining.endsWith('```jso');
2881
- if (partialMatch) {
2882
- // Hold back potential partial match
2883
- const holdBack = remaining.match(/`+j?s?o?n?$/)?.[0]?.length || 0;
2884
- if (holdBack > 0 && remaining.length > holdBack) {
2885
- process.stdout.write(remaining.slice(0, -holdBack));
2886
- }
2887
- remaining = '';
2888
- }
2889
- else {
2890
- process.stdout.write(remaining);
2891
- remaining = '';
2892
- }
2893
- }
2894
- }
2895
- }
2836
+ onOutput: (_text) => {
2837
+ // Track that output was received but don't display it yet.
2838
+ // Keep the spinner running until planTasks() completes so the user
2839
+ // sees a progress indicator instead of static intermediate text.
2840
+ hasOutput = true;
2896
2841
  },
2897
2842
  });
2898
2843
  // Clean up Escape key handling
@@ -2901,9 +2846,9 @@ export class MaistroApp {
2901
2846
  if (escCancelTimeout) {
2902
2847
  clearTimeout(escCancelTimeout);
2903
2848
  }
2904
- // Stop spinner if no output was streamed (error case)
2905
- if (!hasOutput) {
2906
- currentSpinner?.stop();
2849
+ // Stop spinner now that planning is complete
2850
+ if (currentSpinner) {
2851
+ currentSpinner.stop();
2907
2852
  }
2908
2853
  // Handle abort - return to main view without error
2909
2854
  if (result.aborted) {
@@ -2911,17 +2856,21 @@ export class MaistroApp {
2911
2856
  await new Promise(r => setTimeout(r, 500));
2912
2857
  return null;
2913
2858
  }
2914
- if (hasOutput) {
2915
- console.log('\n'); // New line after streamed output
2916
- }
2917
2859
  if (!result.success) {
2918
2860
  console.log(`\x1b[31mError: ${result.error}\x1b[0m\n`);
2919
2861
  await new Promise(r => setTimeout(r, 1500));
2920
2862
  return null;
2921
2863
  }
2922
- // Only print result if we didn't stream it
2923
- if (!hasOutput && result.response) {
2924
- console.log(`${result.response}\n`);
2864
+ // Display response text (filtered to remove JSON blocks) if it's a text-only
2865
+ // response (no questions or tasks). For questions/tasks, the UI handles display.
2866
+ const hasQuestions = result.questions && result.questions.length > 0;
2867
+ const hasTasks = result.tasks && result.tasks.length > 0;
2868
+ if (!hasQuestions && !hasTasks && result.response) {
2869
+ // Strip JSON code blocks from the response for display
2870
+ const displayText = result.response.replace(/```json[\s\S]*?```/g, '').trim();
2871
+ if (displayText) {
2872
+ console.log(`${displayText}\n`);
2873
+ }
2925
2874
  }
2926
2875
  // Check for structured questions first (from new JSON format)
2927
2876
  if (result.questions && result.questions.length > 0) {