knoxis-helper 1.4.3 → 1.4.4

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.
@@ -876,7 +876,15 @@ end tell
876
876
  }
877
877
 
878
878
  /**
879
- * Open terminal on Windows
879
+ * Open terminal on Windows.
880
+ *
881
+ * If the agent is running elevated (admin), Windows won't let us spawn an
882
+ * unelevated child directly — `start cmd` inherits the parent's integrity
883
+ * level. We detect that case and route through a one-shot scheduled task
884
+ * at /rl LIMITED, which runs as the interactive user at medium integrity.
885
+ * That matters because claude's credentials live under the user's real
886
+ * %USERPROFILE%\.claude\, not the admin profile, so an elevated cmd can't
887
+ * find them and hangs on launch.
880
888
  */
881
889
  function openWindowsTerminal(workspaceDir, command) {
882
890
  return new Promise((resolve, reject) => {
@@ -884,16 +892,57 @@ function openWindowsTerminal(workspaceDir, command) {
884
892
  fs.mkdirSync(workspaceDir, { recursive: true });
885
893
  }
886
894
 
887
- const fullCommand = `start cmd /K "cd /d "${workspaceDir}" && ${command}"`;
895
+ // `net session` exits 0 only when elevated.
896
+ exec('net session >nul 2>&1', (elevErr) => {
897
+ const isElevated = !elevErr;
888
898
 
889
- exec(fullCommand, (error) => {
890
- if (error) {
891
- console.error('❌ Windows terminal error:', error);
892
- reject(error);
893
- } else {
894
- console.log('✅ Terminal opened on Windows');
895
- resolve();
899
+ if (!isElevated) {
900
+ const fullCommand = `start cmd /K "cd /d "${workspaceDir}" && ${command}"`;
901
+ exec(fullCommand, (error) => {
902
+ if (error) {
903
+ console.error('❌ Windows terminal error:', error);
904
+ reject(error);
905
+ } else {
906
+ console.log('✅ Terminal opened on Windows');
907
+ resolve();
908
+ }
909
+ });
910
+ return;
896
911
  }
912
+
913
+ const tempBat = path.join(
914
+ os.tmpdir(),
915
+ `knoxis-launch-${process.pid}-${Date.now()}.bat`
916
+ );
917
+ const batContent = `@echo off\r\ncd /d "${workspaceDir}"\r\n${command}\r\ncmd /K\r\n`;
918
+ fs.writeFileSync(tempBat, batContent);
919
+
920
+ const taskName = `KnoxisSpawn_${process.pid}_${Date.now()}`;
921
+ const createCmd = `schtasks /create /tn "${taskName}" /tr "${tempBat}" /sc once /st 00:00 /it /rl LIMITED /f`;
922
+
923
+ exec(createCmd, (cErr) => {
924
+ if (cErr) {
925
+ try { fs.unlinkSync(tempBat); } catch (_) {}
926
+ console.error('❌ Windows terminal error (schtasks create):', cErr);
927
+ return reject(cErr);
928
+ }
929
+
930
+ exec(`schtasks /run /tn "${taskName}"`, (rErr) => {
931
+ // Task registration cleanup. Leave the .bat in %TEMP% — cmd may
932
+ // still have an open handle to it, and the OS cleans %TEMP%.
933
+ setTimeout(() => {
934
+ exec(`schtasks /delete /tn "${taskName}" /f`, () => {});
935
+ }, 5000);
936
+
937
+ if (rErr) {
938
+ console.error('❌ Windows terminal error (schtasks run):', rErr);
939
+ reject(rErr);
940
+ } else {
941
+ console.log('✅ Terminal opened on Windows (de-elevated via scheduled task)');
942
+ resolve();
943
+ }
944
+ });
945
+ });
897
946
  });
898
947
  });
899
948
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knoxis-helper",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "Local helper for Knoxis pair programming - connects your machine to Knoxis on qig.ai",
5
5
  "bin": {
6
6
  "knoxis-helper": "./bin/knoxis-helper.js"