@gricha/perry 0.3.14 → 0.3.16

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.
@@ -98,6 +98,14 @@ export class ApiClient {
98
98
  throw this.wrapError(err);
99
99
  }
100
100
  }
101
+ async syncAllWorkspaces() {
102
+ try {
103
+ return await this.client.workspaces.syncAll();
104
+ }
105
+ catch (err) {
106
+ throw this.wrapError(err);
107
+ }
108
+ }
101
109
  async getPortForwards(name) {
102
110
  try {
103
111
  const result = await this.client.workspaces.getPortForwards({ name });
package/dist/index.js CHANGED
@@ -279,11 +279,35 @@ program
279
279
  }
280
280
  });
281
281
  program
282
- .command('sync <name>')
283
- .description('Sync credentials and files to a running workspace')
284
- .action(async (name) => {
282
+ .command('sync [name]')
283
+ .description('Sync credentials and files to workspaces')
284
+ .option('-a, --all', 'Sync all running workspaces')
285
+ .action(async (name, options) => {
285
286
  try {
286
287
  const client = await getClient();
288
+ if (options.all) {
289
+ console.log('Syncing all running workspaces...');
290
+ const result = await client.syncAllWorkspaces();
291
+ if (result.results.length === 0) {
292
+ console.log('No running workspaces to sync.');
293
+ return;
294
+ }
295
+ for (const r of result.results) {
296
+ if (r.success) {
297
+ console.log(` ✓ ${r.name}`);
298
+ }
299
+ else {
300
+ console.log(` ✗ ${r.name}: ${r.error}`);
301
+ }
302
+ }
303
+ console.log('');
304
+ console.log(`Synced: ${result.synced}, Failed: ${result.failed}`);
305
+ return;
306
+ }
307
+ if (!name) {
308
+ console.error('Error: workspace name required (or use --all)');
309
+ process.exit(1);
310
+ }
287
311
  console.log(`Syncing credentials to workspace '${name}'...`);
288
312
  await client.syncWorkspace(name);
289
313
  console.log(`Workspace '${name}' synced.`);
package/dist/perry-worker CHANGED
Binary file
@@ -137,6 +137,37 @@ export class WorkspaceManager {
137
137
  tempPrefix: 'ws-gitconfig',
138
138
  });
139
139
  }
140
+ async syncEnvironmentFile(containerName) {
141
+ const env = {
142
+ ...this.config.credentials.env,
143
+ };
144
+ if (this.config.agents?.github?.token) {
145
+ env.GITHUB_TOKEN = this.config.agents.github.token;
146
+ }
147
+ if (this.config.agents?.claude_code?.oauth_token) {
148
+ env.CLAUDE_CODE_OAUTH_TOKEN = this.config.agents.claude_code.oauth_token;
149
+ }
150
+ if (Object.keys(env).length === 0) {
151
+ return;
152
+ }
153
+ const lines = Object.entries(env)
154
+ .map(([key, value]) => {
155
+ const escaped = value.includes(' ') || value.includes('"') || value.includes("'")
156
+ ? `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`
157
+ : value;
158
+ return `${key}=${escaped}`;
159
+ })
160
+ .sort();
161
+ const content = lines.join('\n') + '\n';
162
+ const tempFile = path.join(os.tmpdir(), `ws-env-${Date.now()}`);
163
+ try {
164
+ await fs.writeFile(tempFile, content);
165
+ await docker.copyToContainer(containerName, tempFile, '/etc/environment');
166
+ }
167
+ finally {
168
+ await fs.unlink(tempFile).catch(() => { });
169
+ }
170
+ }
140
171
  async setupSSHKeys(containerName, workspaceName) {
141
172
  if (!this.config.ssh) {
142
173
  return;
@@ -189,6 +220,7 @@ export class WorkspaceManager {
189
220
  async setupWorkspaceCredentials(containerName, workspaceName) {
190
221
  await this.copyGitConfig(containerName);
191
222
  await this.copyCredentialFiles(containerName);
223
+ await this.syncEnvironmentFile(containerName);
192
224
  await syncAllAgents(containerName, this.config);
193
225
  await this.copyPerryWorker(containerName);
194
226
  await this.startWorkerServer(containerName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gricha/perry",
3
- "version": "0.3.14",
3
+ "version": "0.3.16",
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": {