@gricha/perry 0.3.17 → 0.3.18

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/index.js CHANGED
@@ -751,25 +751,133 @@ program
751
751
  console.log('Already up to date.');
752
752
  process.exit(0);
753
753
  }
754
- const agentRunning = await checkLocalAgent();
755
- if (agentRunning) {
756
- console.error('');
757
- console.error('Warning: Perry agent is currently running.');
758
- console.error('The update may fail with "Text file busy" error.');
759
- console.error('');
760
- console.error('Stop the agent first with:');
761
- console.error(' perry agent kill');
762
- console.error('');
763
- console.error('Then run the update again.');
764
- process.exit(1);
754
+ const configDir = getConfigDir();
755
+ const agentConfig = await loadAgentConfig(configDir);
756
+ const agentPort = agentConfig.port || DEFAULT_AGENT_PORT;
757
+ async function checkAgentRunning() {
758
+ try {
759
+ const response = await fetch(`http://localhost:${agentPort}/health`, {
760
+ signal: AbortSignal.timeout(1000),
761
+ });
762
+ return response.ok;
763
+ }
764
+ catch {
765
+ return false;
766
+ }
767
+ }
768
+ async function waitForAgentReady(timeoutMs = 15000) {
769
+ const deadline = Date.now() + timeoutMs;
770
+ while (Date.now() < deadline) {
771
+ if (await checkAgentRunning()) {
772
+ return true;
773
+ }
774
+ await new Promise((r) => setTimeout(r, 250));
775
+ }
776
+ return false;
777
+ }
778
+ async function runProcess(command, args, inherit = true) {
779
+ const proc = spawn(command, args, { stdio: inherit ? 'inherit' : 'ignore' });
780
+ return await new Promise((resolve) => proc.on('close', (code) => resolve(code ?? 0)));
781
+ }
782
+ const serviceStatus = await getServiceStatus();
783
+ const wasSystemdRunning = serviceStatus.running;
784
+ const wasAgentRunning = wasSystemdRunning ? true : await checkAgentRunning();
785
+ if (wasAgentRunning) {
786
+ console.log('');
787
+ console.log('Agent is running; update will restart it.');
788
+ console.log('');
789
+ if (wasSystemdRunning) {
790
+ const stopCode = await runProcess('systemctl', ['--user', 'stop', 'perry-agent']);
791
+ if (stopCode !== 0) {
792
+ console.error('Failed to stop agent service.');
793
+ process.exit(stopCode);
794
+ }
795
+ }
796
+ else {
797
+ await runProcess('pkill', ['-f', 'perry.*agent.*run']);
798
+ await new Promise((r) => setTimeout(r, 500));
799
+ const stillRunning = await checkAgentRunning();
800
+ if (stillRunning) {
801
+ await runProcess('pkill', ['-9', '-f', 'perry.*agent.*run']);
802
+ }
803
+ }
765
804
  }
766
805
  console.log(`Updating Perry from ${currentVersion} to ${latestVersion}...`);
767
- const child = spawn('bash', ['-c', 'curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash'], {
768
- stdio: 'inherit',
769
- });
770
- child.on('close', (code) => {
771
- process.exit(code ?? 0);
772
- });
806
+ const updateExitCode = await runProcess('bash', [
807
+ '-c',
808
+ 'curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash',
809
+ ]);
810
+ if (updateExitCode !== 0) {
811
+ process.exit(updateExitCode);
812
+ }
813
+ if (wasSystemdRunning) {
814
+ const startCode = await runProcess('systemctl', ['--user', 'start', 'perry-agent']);
815
+ if (startCode !== 0) {
816
+ console.error('Updated perry, but failed to start agent service.');
817
+ process.exit(startCode);
818
+ }
819
+ }
820
+ else if (wasAgentRunning) {
821
+ const proc = spawn('perry', ['agent', 'run', '--port', String(agentPort), '--config-dir', configDir], {
822
+ detached: true,
823
+ stdio: 'ignore',
824
+ });
825
+ proc.unref();
826
+ }
827
+ if (!wasAgentRunning) {
828
+ console.log('');
829
+ console.log('Agent was not running; skipping workspace sync.');
830
+ console.log('To update running workspaces, start the agent and run:');
831
+ console.log(' perry sync --all');
832
+ process.exit(0);
833
+ }
834
+ const agentReady = await waitForAgentReady();
835
+ if (!agentReady) {
836
+ console.log('');
837
+ console.error('Updated perry, but agent did not become ready in time.');
838
+ if (wasSystemdRunning) {
839
+ console.error('Check logs with:');
840
+ console.error(' journalctl --user -u perry-agent -f');
841
+ }
842
+ console.error('Then sync workspaces with:');
843
+ console.error(' perry sync --all');
844
+ process.exit(1);
845
+ }
846
+ try {
847
+ console.log('');
848
+ console.log('Syncing all running workspaces...');
849
+ const client = createApiClient(`localhost:${agentPort}`);
850
+ const result = await client.syncAllWorkspaces();
851
+ if (result.results.length === 0) {
852
+ console.log('No running workspaces to sync.');
853
+ process.exit(0);
854
+ }
855
+ for (const r of result.results) {
856
+ if (r.success) {
857
+ console.log(` ✓ ${r.name}`);
858
+ }
859
+ else {
860
+ console.log(` ✗ ${r.name}: ${r.error}`);
861
+ }
862
+ }
863
+ console.log('');
864
+ console.log(`Synced: ${result.synced}, Failed: ${result.failed}`);
865
+ }
866
+ catch (err) {
867
+ console.error('');
868
+ console.error('Updated perry, but workspace sync failed.');
869
+ if (err instanceof ApiClientError) {
870
+ console.error(err.message);
871
+ }
872
+ else if (err instanceof Error) {
873
+ console.error(err.message);
874
+ }
875
+ else {
876
+ console.error(String(err));
877
+ }
878
+ console.error('Run `perry sync --all` after the agent is reachable.');
879
+ }
880
+ process.exit(0);
773
881
  });
774
882
  program
775
883
  .command('build')
package/dist/perry-worker CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gricha/perry",
3
- "version": "0.3.17",
3
+ "version": "0.3.18",
4
4
  "description": "Self-contained CLI for spinning up Docker-in-Docker development environments with SSH and proxy helpers.",
5
5
  "type": "module",
6
6
  "bin": {