sylas-ai 0.2.21 → 0.2.23

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.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/dist/app.js +2 -2
  3. package/dist/app.js.map +1 -1
  4. package/dist/commands/RefreshTokenCommand.js +2 -2
  5. package/dist/commands/RefreshTokenCommand.js.map +1 -1
  6. package/dist/commands/SelfAddRepoCommand.d.ts +1 -0
  7. package/dist/commands/SelfAddRepoCommand.d.ts.map +1 -1
  8. package/dist/commands/SelfAddRepoCommand.js +20 -101
  9. package/dist/commands/SelfAddRepoCommand.js.map +1 -1
  10. package/dist/commands/SelfAuthCommand.d.ts +1 -7
  11. package/dist/commands/SelfAuthCommand.d.ts.map +1 -1
  12. package/dist/commands/SelfAuthCommand.js +9 -142
  13. package/dist/commands/SelfAuthCommand.js.map +1 -1
  14. package/dist/commands/StartCommand.d.ts.map +1 -1
  15. package/dist/commands/StartCommand.js +16 -1
  16. package/dist/commands/StartCommand.js.map +1 -1
  17. package/dist/services/AuthFlowService.d.ts +20 -0
  18. package/dist/services/AuthFlowService.d.ts.map +1 -0
  19. package/dist/{src/commands/SelfAuthCommand.js → services/AuthFlowService.js} +10 -82
  20. package/dist/services/AuthFlowService.js.map +1 -0
  21. package/dist/services/OnboardingService.d.ts +15 -0
  22. package/dist/services/OnboardingService.d.ts.map +1 -0
  23. package/dist/services/OnboardingService.js +111 -0
  24. package/dist/services/OnboardingService.js.map +1 -0
  25. package/dist/services/RepoService.d.ts +33 -0
  26. package/dist/services/RepoService.d.ts.map +1 -0
  27. package/dist/services/RepoService.js +118 -0
  28. package/dist/services/RepoService.js.map +1 -0
  29. package/dist/utils/openUrl.d.ts +7 -0
  30. package/dist/utils/openUrl.d.ts.map +1 -0
  31. package/dist/utils/openUrl.js +33 -0
  32. package/dist/utils/openUrl.js.map +1 -0
  33. package/package.json +12 -11
  34. package/dist/src/Application.d.ts +0 -75
  35. package/dist/src/Application.d.ts.map +0 -1
  36. package/dist/src/Application.js +0 -289
  37. package/dist/src/Application.js.map +0 -1
  38. package/dist/src/app.d.ts +0 -3
  39. package/dist/src/app.d.ts.map +0 -1
  40. package/dist/src/app.js +0 -93
  41. package/dist/src/app.js.map +0 -1
  42. package/dist/src/commands/AuthCommand.d.ts +0 -8
  43. package/dist/src/commands/AuthCommand.d.ts.map +0 -1
  44. package/dist/src/commands/AuthCommand.js +0 -70
  45. package/dist/src/commands/AuthCommand.js.map +0 -1
  46. package/dist/src/commands/CheckTokensCommand.d.ts +0 -8
  47. package/dist/src/commands/CheckTokensCommand.d.ts.map +0 -1
  48. package/dist/src/commands/CheckTokensCommand.js +0 -53
  49. package/dist/src/commands/CheckTokensCommand.js.map +0 -1
  50. package/dist/src/commands/ICommand.d.ts +0 -38
  51. package/dist/src/commands/ICommand.d.ts.map +0 -1
  52. package/dist/src/commands/ICommand.js +0 -37
  53. package/dist/src/commands/ICommand.js.map +0 -1
  54. package/dist/src/commands/RefreshTokenCommand.d.ts +0 -8
  55. package/dist/src/commands/RefreshTokenCommand.d.ts.map +0 -1
  56. package/dist/src/commands/RefreshTokenCommand.js +0 -152
  57. package/dist/src/commands/RefreshTokenCommand.js.map +0 -1
  58. package/dist/src/commands/SelfAddRepoCommand.d.ts +0 -17
  59. package/dist/src/commands/SelfAddRepoCommand.d.ts.map +0 -1
  60. package/dist/src/commands/SelfAddRepoCommand.js +0 -164
  61. package/dist/src/commands/SelfAddRepoCommand.js.map +0 -1
  62. package/dist/src/commands/SelfAuthCommand.d.ts +0 -16
  63. package/dist/src/commands/SelfAuthCommand.d.ts.map +0 -1
  64. package/dist/src/commands/SelfAuthCommand.js.map +0 -1
  65. package/dist/src/commands/StartCommand.d.ts +0 -8
  66. package/dist/src/commands/StartCommand.d.ts.map +0 -1
  67. package/dist/src/commands/StartCommand.js +0 -76
  68. package/dist/src/commands/StartCommand.js.map +0 -1
  69. package/dist/src/config/constants.d.ts +0 -12
  70. package/dist/src/config/constants.d.ts.map +0 -1
  71. package/dist/src/config/constants.js +0 -19
  72. package/dist/src/config/constants.js.map +0 -1
  73. package/dist/src/config/types.d.ts +0 -21
  74. package/dist/src/config/types.d.ts.map +0 -1
  75. package/dist/src/config/types.js +0 -2
  76. package/dist/src/config/types.js.map +0 -1
  77. package/dist/src/services/ConfigService.d.ts +0 -37
  78. package/dist/src/services/ConfigService.d.ts.map +0 -1
  79. package/dist/src/services/ConfigService.js +0 -121
  80. package/dist/src/services/ConfigService.js.map +0 -1
  81. package/dist/src/services/Logger.d.ts +0 -77
  82. package/dist/src/services/Logger.d.ts.map +0 -1
  83. package/dist/src/services/Logger.js +0 -100
  84. package/dist/src/services/Logger.js.map +0 -1
  85. package/dist/src/services/WorkerService.d.ts +0 -59
  86. package/dist/src/services/WorkerService.d.ts.map +0 -1
  87. package/dist/src/services/WorkerService.js +0 -220
  88. package/dist/src/services/WorkerService.js.map +0 -1
  89. package/dist/src/ui/CLIPrompts.d.ts +0 -18
  90. package/dist/src/ui/CLIPrompts.d.ts.map +0 -1
  91. package/dist/src/ui/CLIPrompts.js +0 -53
  92. package/dist/src/ui/CLIPrompts.js.map +0 -1
  93. package/dist/vitest.config.d.ts +0 -3
  94. package/dist/vitest.config.d.ts.map +0 -1
  95. package/dist/vitest.config.js +0 -13
  96. package/dist/vitest.config.js.map +0 -1
@@ -1,83 +1,12 @@
1
- import { readFileSync, writeFileSync } from "node:fs";
2
- import { resolve } from "node:path";
1
+ import { writeFileSync } from "node:fs";
3
2
  import { LinearClient } from "@linear/sdk";
4
3
  import Fastify from "fastify";
5
- import open from "open";
6
- import { DEFAULT_CONFIG_FILENAME } from "sylas-core";
7
- import { BaseCommand } from "./ICommand.js";
8
- /**
9
- * Self-auth command - authenticate with Linear OAuth directly from CLI
10
- * Handles the complete OAuth flow without requiring EdgeWorker
11
- */
12
- export class SelfAuthCommand extends BaseCommand {
4
+ import { openUrl } from "../utils/openUrl.js";
5
+ export class AuthFlowService {
13
6
  server = null;
14
7
  callbackPort = parseInt(process.env.SYLAS_SERVER_PORT || "3456", 10);
15
- async execute(_args) {
16
- console.log("\nSylas Linear Self-Authentication");
17
- this.logDivider();
18
- // Check required environment variables
19
- const clientId = process.env.LINEAR_CLIENT_ID;
20
- const clientSecret = process.env.LINEAR_CLIENT_SECRET;
21
- const baseUrl = process.env.SYLAS_BASE_URL;
22
- if (!clientId || !clientSecret || !baseUrl) {
23
- this.logError("Missing required environment variables:");
24
- if (!clientId)
25
- console.log(" - LINEAR_CLIENT_ID");
26
- if (!clientSecret)
27
- console.log(" - LINEAR_CLIENT_SECRET");
28
- if (!baseUrl)
29
- console.log(" - SYLAS_BASE_URL");
30
- console.log("\nSet these in your shell profile (.zshrc):");
31
- console.log(" export LINEAR_CLIENT_ID='your-client-id'");
32
- console.log(" export LINEAR_CLIENT_SECRET='your-client-secret'");
33
- console.log(" export SYLAS_BASE_URL='https://your-tunnel-domain.com'");
34
- process.exit(1);
35
- }
36
- // Check config file exists
37
- const configPath = resolve(this.app.sylasHome, DEFAULT_CONFIG_FILENAME);
38
- let config;
39
- try {
40
- config = JSON.parse(readFileSync(configPath, "utf-8"));
41
- }
42
- catch {
43
- this.logError(`Config file not found: ${configPath}`);
44
- console.log("Run 'sylas' first to create initial configuration.");
45
- process.exit(1);
46
- }
47
- console.log("Configuration:");
48
- console.log(` Client ID: ${clientId.substring(0, 20)}...`);
49
- console.log(` Base URL: ${baseUrl}`);
50
- console.log(` Config: ${configPath}`);
51
- console.log(` Callback port: ${this.callbackPort}`);
52
- console.log();
53
- try {
54
- // Start temporary server to receive OAuth callback
55
- const authCode = await this.waitForCallback(clientId);
56
- // Exchange code for tokens
57
- console.log("Exchanging code for tokens...");
58
- const tokens = await this.exchangeCodeForTokens(authCode, clientId, clientSecret);
59
- this.logSuccess(`Got access token: ${tokens.accessToken.substring(0, 30)}...`);
60
- // Fetch workspace info
61
- console.log("Fetching workspace info...");
62
- const workspace = await this.fetchWorkspaceInfo(tokens.accessToken);
63
- this.logSuccess(`Workspace: ${workspace.name} (${workspace.id})`);
64
- // Update config.json
65
- console.log("Saving tokens to config.json...");
66
- this.overwriteRepoConfigTokens(config, configPath, tokens, workspace);
67
- const updatedCount = config.repositories.filter((r) => r.linearWorkspaceId === workspace.id).length;
68
- this.logSuccess(`Updated ${updatedCount} repository/repositories`);
69
- console.log();
70
- this.logSuccess("Authentication complete! Restart sylas to use the new tokens.");
71
- process.exit(0);
72
- }
73
- catch (error) {
74
- this.logError(`Authentication failed: ${error.message}`);
75
- process.exit(1);
76
- }
77
- finally {
78
- // One of the key guarantees of finally — it runs regardless of how the try block exits (return, throw, or normal completion).
79
- await this.cleanup();
80
- }
8
+ getCallbackPort() {
9
+ return this.callbackPort;
81
10
  }
82
11
  async waitForCallback(clientId) {
83
12
  return new Promise((resolve, reject) => {
@@ -87,8 +16,6 @@ export class SelfAuthCommand extends BaseCommand {
87
16
  return;
88
17
  }
89
18
  const redirectUri = `${baseUrl}/callback`;
90
- // https://linear.app/developers/oauth-2-0-authentication
91
- // https://linear.app/developers/oauth-actor-authorization
92
19
  const oauthUrl = `https://linear.app/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=write,app:assignable,app:mentionable&actor=app`;
93
20
  this.server = Fastify({ logger: false });
94
21
  this.server.get("/callback", async (request, reply) => {
@@ -141,7 +68,7 @@ export class SelfAuthCommand extends BaseCommand {
141
68
  console.log("If browser doesn't open, visit:");
142
69
  console.log(oauthUrl);
143
70
  console.log();
144
- open(oauthUrl).catch(() => {
71
+ openUrl(oauthUrl).catch(() => {
145
72
  console.log("Could not open browser automatically.");
146
73
  });
147
74
  })
@@ -152,8 +79,10 @@ export class SelfAuthCommand extends BaseCommand {
152
79
  }
153
80
  async exchangeCodeForTokens(code, clientId, clientSecret) {
154
81
  const baseUrl = process.env.SYLAS_BASE_URL;
82
+ if (!baseUrl) {
83
+ throw new Error("SYLAS_BASE_URL environment variable is required");
84
+ }
155
85
  const redirectUri = `${baseUrl}/callback`;
156
- // https://linear.app/developers/oauth-2-0-authentication
157
86
  const response = await fetch("https://api.linear.app/oauth/token", {
158
87
  method: "POST",
159
88
  headers: {
@@ -190,7 +119,6 @@ export class SelfAuthCommand extends BaseCommand {
190
119
  return { id: organization.id, name: organization.name || organization.id };
191
120
  }
192
121
  overwriteRepoConfigTokens(config, configPath, tokens, workspace) {
193
- // Update all repositories matching this workspace (or unset workspace)
194
122
  for (const repo of config.repositories) {
195
123
  if (repo.linearWorkspaceId === workspace.id ||
196
124
  !repo.linearWorkspaceId ||
@@ -210,4 +138,4 @@ export class SelfAuthCommand extends BaseCommand {
210
138
  }
211
139
  }
212
140
  }
213
- //# sourceMappingURL=SelfAuthCommand.js.map
141
+ //# sourceMappingURL=AuthFlowService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthFlowService.js","sourceRoot":"","sources":["../../src/services/AuthFlowService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Application } from "../Application.js";
2
+ export declare class OnboardingService {
3
+ private readonly app;
4
+ private rl;
5
+ private authFlow;
6
+ private repoService;
7
+ constructor(app: Application);
8
+ run(): Promise<boolean>;
9
+ private printWelcome;
10
+ private getReadline;
11
+ private prompt;
12
+ private promptRequired;
13
+ private cleanupReadline;
14
+ }
15
+ //# sourceMappingURL=OnboardingService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnboardingService.d.ts","sourceRoot":"","sources":["../../src/services/OnboardingService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,qBAAa,iBAAiB;IAKjB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,WAAW,CAAc;gBAEJ,GAAG,EAAE,WAAW;IAIvC,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;IA0E7B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,MAAM;YAMA,cAAc;IAW5B,OAAO,CAAC,eAAe;CAMvB"}
@@ -0,0 +1,111 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import * as readline from "node:readline";
4
+ import dotenv from "dotenv";
5
+ import { AuthFlowService } from "./AuthFlowService.js";
6
+ import { RepoService } from "./RepoService.js";
7
+ export class OnboardingService {
8
+ app;
9
+ rl = null;
10
+ authFlow = new AuthFlowService();
11
+ repoService;
12
+ constructor(app) {
13
+ this.app = app;
14
+ this.repoService = new RepoService(app.sylasHome);
15
+ }
16
+ async run() {
17
+ try {
18
+ this.printWelcome();
19
+ const clientId = await this.promptRequired("LINEAR_CLIENT_ID: ");
20
+ const clientSecret = await this.promptRequired("LINEAR_CLIENT_SECRET: ");
21
+ const baseUrl = await this.promptRequired("SYLAS_BASE_URL (e.g., https://your-machine.tailnet.ts.net): ");
22
+ const envPath = join(this.app.sylasHome, ".env");
23
+ const existing = existsSync(envPath)
24
+ ? readFileSync(envPath, "utf-8")
25
+ : "";
26
+ const parsed = dotenv.parse(existing);
27
+ parsed.LINEAR_CLIENT_ID = clientId;
28
+ parsed.LINEAR_CLIENT_SECRET = clientSecret;
29
+ parsed.SYLAS_BASE_URL = baseUrl;
30
+ const merged = Object.entries(parsed)
31
+ .map(([k, v]) => `${k}=${v}`)
32
+ .join("\n");
33
+ writeFileSync(envPath, `${merged}\n`, "utf-8");
34
+ dotenv.config({ path: envPath, override: true });
35
+ if (!this.app.config.exists()) {
36
+ this.app.config.save({ repositories: [] });
37
+ }
38
+ console.log("\nStarting Linear OAuth...");
39
+ const authCode = await this.authFlow.waitForCallback(clientId);
40
+ const tokens = await this.authFlow.exchangeCodeForTokens(authCode, clientId, clientSecret);
41
+ const workspace = await this.authFlow.fetchWorkspaceInfo(tokens.accessToken);
42
+ console.log(`Connected workspace: ${workspace.name}`);
43
+ const repoUrl = await this.repoService.promptForRepoUrl((question) => this.prompt(question));
44
+ const configPath = this.app.config.getConfigPath();
45
+ const config = this.app.config.load();
46
+ if (!config.repositories) {
47
+ config.repositories = [];
48
+ }
49
+ await this.repoService.cloneAndAddRepo({
50
+ url: repoUrl,
51
+ config,
52
+ configPath,
53
+ credentials: {
54
+ id: workspace.id,
55
+ name: workspace.name,
56
+ token: tokens.accessToken,
57
+ refreshToken: tokens.refreshToken,
58
+ },
59
+ });
60
+ console.log("\nSetup complete. Starting Sylas...");
61
+ return true;
62
+ }
63
+ catch (error) {
64
+ this.app.logger.error(`Onboarding failed: ${error.message}`);
65
+ return false;
66
+ }
67
+ finally {
68
+ await this.authFlow.cleanup();
69
+ this.cleanupReadline();
70
+ }
71
+ }
72
+ printWelcome() {
73
+ console.log("\nWelcome to Sylas.");
74
+ console.log("Let's run first-time setup.");
75
+ if (!existsSync(this.app.config.getConfigPath())) {
76
+ console.log("We'll create your config and connect your first repository.");
77
+ }
78
+ console.log();
79
+ }
80
+ getReadline() {
81
+ if (!this.rl) {
82
+ this.rl = readline.createInterface({
83
+ input: process.stdin,
84
+ output: process.stdout,
85
+ });
86
+ }
87
+ return this.rl;
88
+ }
89
+ prompt(question) {
90
+ return new Promise((resolve) => {
91
+ this.getReadline().question(question, (answer) => resolve(answer.trim()));
92
+ });
93
+ }
94
+ async promptRequired(question) {
95
+ let value = "";
96
+ while (!value) {
97
+ value = await this.prompt(question);
98
+ if (!value) {
99
+ console.log("This value is required.");
100
+ }
101
+ }
102
+ return value;
103
+ }
104
+ cleanupReadline() {
105
+ if (this.rl) {
106
+ this.rl.close();
107
+ this.rl = null;
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=OnboardingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnboardingService.js","sourceRoot":"","sources":["../../src/services/OnboardingService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type EdgeConfig } from "sylas-core";
2
+ export interface WorkspaceCredentials {
3
+ id: string;
4
+ name: string;
5
+ token: string;
6
+ refreshToken?: string;
7
+ }
8
+ export interface AddRepositoryResult {
9
+ id: string;
10
+ repoName: string;
11
+ repositoryPath: string;
12
+ workspace: WorkspaceCredentials;
13
+ }
14
+ export type PromptFn = (question: string) => Promise<string>;
15
+ interface CloneAndAddRepoInput {
16
+ url: string;
17
+ config: EdgeConfig;
18
+ configPath: string;
19
+ credentials?: WorkspaceCredentials;
20
+ workspaceName?: string;
21
+ prompt?: PromptFn;
22
+ }
23
+ export declare class RepoService {
24
+ private readonly sylasHome;
25
+ constructor(sylasHome: string);
26
+ promptForRepoUrl(prompt: PromptFn): Promise<string>;
27
+ cloneAndAddRepo(input: CloneAndAddRepoInput): Promise<AddRepositoryResult>;
28
+ getWorkspaceCredentials(config: EdgeConfig): WorkspaceCredentials[];
29
+ selectWorkspace(workspaces: WorkspaceCredentials[], workspaceName?: string, prompt?: PromptFn): Promise<WorkspaceCredentials>;
30
+ private extractRepoName;
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=RepoService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoService.d.ts","sourceRoot":"","sources":["../../src/services/RepoService.ts"],"names":[],"mappings":"AAIA,OAAO,EAGN,KAAK,UAAU,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,oBAAoB,CAAC;CAChC;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE7D,UAAU,oBAAoB;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,qBAAa,WAAW;IACX,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAExC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnD,eAAe,CACpB,KAAK,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC;IAmE/B,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,oBAAoB,EAAE;IAqB7D,eAAe,CACpB,UAAU,EAAE,oBAAoB,EAAE,EAClC,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,QAAQ,GACf,OAAO,CAAC,oBAAoB,CAAC;IAqChC,OAAO,CAAC,eAAe;CAMvB"}
@@ -0,0 +1,118 @@
1
+ import { execSync } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { existsSync, writeFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import { DEFAULT_BASE_BRANCH, DEFAULT_WORKTREES_DIR, } from "sylas-core";
6
+ export class RepoService {
7
+ sylasHome;
8
+ constructor(sylasHome) {
9
+ this.sylasHome = sylasHome;
10
+ }
11
+ async promptForRepoUrl(prompt) {
12
+ const url = (await prompt("Repository URL: ")).trim();
13
+ if (!url) {
14
+ throw new Error("URL is required");
15
+ }
16
+ return url;
17
+ }
18
+ async cloneAndAddRepo(input) {
19
+ const { url, config, configPath, credentials, workspaceName, prompt } = input;
20
+ if (!config.repositories) {
21
+ config.repositories = [];
22
+ }
23
+ const repoName = this.extractRepoName(url);
24
+ if (!repoName) {
25
+ throw new Error("Could not extract repo name from URL");
26
+ }
27
+ if (config.repositories.some((r) => r.name === repoName)) {
28
+ throw new Error(`Repository '${repoName}' already exists in config`);
29
+ }
30
+ const selectedWorkspace = credentials
31
+ ? credentials
32
+ : await this.selectWorkspace(this.getWorkspaceCredentials(config), workspaceName, prompt);
33
+ const repositoryPath = resolve(this.sylasHome, "repos", repoName);
34
+ if (existsSync(repositoryPath)) {
35
+ console.log(`Repository already exists at ${repositoryPath}`);
36
+ }
37
+ else {
38
+ console.log(`Cloning ${url}...`);
39
+ try {
40
+ execSync(`git clone ${url} ${repositoryPath}`, { stdio: "inherit" });
41
+ }
42
+ catch {
43
+ throw new Error("Failed to clone repository");
44
+ }
45
+ }
46
+ const id = randomUUID();
47
+ config.repositories.push({
48
+ id,
49
+ name: repoName,
50
+ repositoryPath,
51
+ baseBranch: DEFAULT_BASE_BRANCH,
52
+ workspaceBaseDir: resolve(this.sylasHome, DEFAULT_WORKTREES_DIR),
53
+ linearWorkspaceId: selectedWorkspace.id,
54
+ linearWorkspaceName: selectedWorkspace.name,
55
+ linearToken: selectedWorkspace.token,
56
+ linearRefreshToken: selectedWorkspace.refreshToken,
57
+ isActive: true,
58
+ });
59
+ writeFileSync(configPath, JSON.stringify(config, null, "\t"), "utf-8");
60
+ return {
61
+ id,
62
+ repoName,
63
+ repositoryPath,
64
+ workspace: selectedWorkspace,
65
+ };
66
+ }
67
+ getWorkspaceCredentials(config) {
68
+ const workspaces = new Map();
69
+ for (const repo of config.repositories || []) {
70
+ if (repo.linearWorkspaceId &&
71
+ repo.linearToken &&
72
+ !workspaces.has(repo.linearWorkspaceId)) {
73
+ workspaces.set(repo.linearWorkspaceId, {
74
+ id: repo.linearWorkspaceId,
75
+ name: repo.linearWorkspaceName || repo.linearWorkspaceId,
76
+ token: repo.linearToken,
77
+ refreshToken: repo.linearRefreshToken,
78
+ });
79
+ }
80
+ }
81
+ return Array.from(workspaces.values());
82
+ }
83
+ async selectWorkspace(workspaces, workspaceName, prompt) {
84
+ if (workspaces.length === 0) {
85
+ throw new Error("No Linear credentials found. Run 'sylas self-auth' first.");
86
+ }
87
+ if (workspaces.length === 1) {
88
+ return workspaces[0];
89
+ }
90
+ if (workspaceName) {
91
+ const foundWorkspace = workspaces.find((w) => w.name === workspaceName);
92
+ if (!foundWorkspace) {
93
+ throw new Error(`Workspace '${workspaceName}' not found`);
94
+ }
95
+ return foundWorkspace;
96
+ }
97
+ if (!prompt) {
98
+ throw new Error("Workspace selection prompt is required");
99
+ }
100
+ console.log("\nAvailable workspaces:");
101
+ workspaces.forEach((workspace, index) => {
102
+ console.log(` ${index + 1}. ${workspace.name}`);
103
+ });
104
+ const choice = await prompt(`Select workspace [1-${workspaces.length}]: `);
105
+ const idx = parseInt(choice, 10) - 1;
106
+ if (idx < 0 || idx >= workspaces.length) {
107
+ throw new Error("Invalid selection");
108
+ }
109
+ return workspaces[idx];
110
+ }
111
+ extractRepoName(url) {
112
+ return url
113
+ .split("/")
114
+ .pop()
115
+ ?.replace(/\.git$/, "");
116
+ }
117
+ }
118
+ //# sourceMappingURL=RepoService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoService.js","sourceRoot":"","sources":["../../src/services/RepoService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Open a URL in the default browser using platform-native commands.
3
+ * Replaces the `open` npm package to avoid transitive dependency issues
4
+ * (define-lazy-prop ESM resolution bug in bunx).
5
+ */
6
+ export declare function openUrl(url: string): Promise<void>;
7
+ //# sourceMappingURL=openUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openUrl.d.ts","sourceRoot":"","sources":["../../src/utils/openUrl.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BxD"}
@@ -0,0 +1,33 @@
1
+ import { exec } from "node:child_process";
2
+ /**
3
+ * Open a URL in the default browser using platform-native commands.
4
+ * Replaces the `open` npm package to avoid transitive dependency issues
5
+ * (define-lazy-prop ESM resolution bug in bunx).
6
+ */
7
+ export async function openUrl(url) {
8
+ const platform = process.platform;
9
+ let command;
10
+ switch (platform) {
11
+ case "darwin":
12
+ command = `open ${JSON.stringify(url)}`;
13
+ break;
14
+ case "win32":
15
+ command = `start "" ${JSON.stringify(url)}`;
16
+ break;
17
+ default:
18
+ // Linux and other Unix-like systems
19
+ command = `xdg-open ${JSON.stringify(url)}`;
20
+ break;
21
+ }
22
+ return new Promise((resolve, reject) => {
23
+ exec(command, (error) => {
24
+ if (error) {
25
+ reject(error);
26
+ }
27
+ else {
28
+ resolve();
29
+ }
30
+ });
31
+ });
32
+ }
33
+ //# sourceMappingURL=openUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openUrl.js","sourceRoot":"","sources":["../../src/utils/openUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,OAAe,CAAC;IAEpB,QAAQ,QAAQ,EAAE,CAAC;QAClB,KAAK,QAAQ;YACZ,OAAO,GAAG,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM;QACP,KAAK,OAAO;YACX,OAAO,GAAG,YAAY,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM;QACP;YACC,oCAAoC;YACpC,OAAO,GAAG,YAAY,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM;IACR,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACX,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "sylas-ai",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "AI-powered Linear issue automation using Claude",
5
- "main": "dist/src/app.js",
6
- "types": "dist/src/app.d.ts",
5
+ "main": "dist/app.js",
6
+ "types": "dist/app.d.ts",
7
7
  "bin": {
8
- "sylas": "./dist/src/app.js"
8
+ "sylas": "./dist/app.js"
9
9
  },
10
10
  "type": "module",
11
11
  "files": [
@@ -38,13 +38,14 @@
38
38
  "file-type": "^21.0.0",
39
39
  "fs-extra": "^11.3.0",
40
40
  "node-fetch": "^2.7.0",
41
- "open": "^10.0.0",
42
41
  "zod": "^4.3.5",
43
- "sylas-cloudflare-tunnel-client": "0.2.21",
44
- "sylas-config-updater": "0.2.21",
45
- "sylas-core": "0.2.21",
46
- "sylas-edge-worker": "0.2.21",
47
- "sylas-claude-runner": "0.2.21"
42
+ "sylas-config-updater": "0.2.23",
43
+ "sylas-core": "0.2.23",
44
+ "sylas-claude-runner": "0.2.23",
45
+ "sylas-opencode-runner": "0.2.23",
46
+ "sylas-edge-worker": "0.2.23",
47
+ "sylas-cloudflare-tunnel-client": "0.2.23",
48
+ "sylas-codex-runner": "0.2.23"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@types/node": "^20.0.0",
@@ -53,7 +54,7 @@
53
54
  },
54
55
  "scripts": {
55
56
  "build": "tsc",
56
- "start": "node dist/src/app.js",
57
+ "start": "node dist/app.js",
57
58
  "dev": "tsc --watch",
58
59
  "test": "bun test",
59
60
  "test:run": "bun test",
@@ -1,75 +0,0 @@
1
- import { GitService, SharedApplicationServer } from "sylas-edge-worker";
2
- import { ConfigService } from "./services/ConfigService.js";
3
- import { Logger } from "./services/Logger.js";
4
- import { WorkerService } from "./services/WorkerService.js";
5
- /**
6
- * Main application context providing access to services
7
- */
8
- export declare class Application {
9
- readonly sylasHome: string;
10
- readonly config: ConfigService;
11
- readonly git: GitService;
12
- readonly worker: WorkerService;
13
- readonly logger: Logger;
14
- readonly version: string;
15
- private envWatcher?;
16
- private configWatcher?;
17
- private isInSetupWaitingMode;
18
- private isInIdleMode;
19
- private readonly envFilePath;
20
- constructor(sylasHome: string, customEnvPath?: string, version?: string);
21
- /**
22
- * Load environment variables from the configured env file path
23
- */
24
- private loadEnvFile;
25
- /**
26
- * Setup file watcher for .env file to reload on changes
27
- */
28
- private setupEnvFileWatcher;
29
- /**
30
- * Ensure required Sylas directories exist
31
- * Creates: ~/.sylas/repos, ~/.sylas/worktrees, ~/.sylas/mcp-configs
32
- */
33
- private ensureRequiredDirectories;
34
- /**
35
- * Get proxy URL from environment or use default
36
- */
37
- getProxyUrl(): string;
38
- /**
39
- * Check if using default proxy
40
- */
41
- isUsingDefaultProxy(): boolean;
42
- /**
43
- * Create a temporary SharedApplicationServer for OAuth
44
- */
45
- createTempServer(): Promise<SharedApplicationServer>;
46
- /**
47
- * Enable setup waiting mode and start watching config.json for repositories
48
- */
49
- enableSetupWaitingMode(): void;
50
- /**
51
- * Enable idle mode (post-onboarding, no repositories) and start watching config.json
52
- */
53
- enableIdleMode(): void;
54
- /**
55
- * Setup file watcher for config.json to detect when repositories are added
56
- */
57
- private startConfigWatcher;
58
- /**
59
- * Remove SYLAS_SETUP_PENDING flag from .env file
60
- */
61
- private removeSetupPendingFlag;
62
- /**
63
- * Transition from setup waiting mode to normal operation
64
- */
65
- private transitionToNormalMode;
66
- /**
67
- * Handle graceful shutdown
68
- */
69
- shutdown(): Promise<void>;
70
- /**
71
- * Setup process signal handlers
72
- */
73
- setupSignalHandlers(): void;
74
- }
75
- //# sourceMappingURL=Application.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../src/Application.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;GAEG;AACH,qBAAa,WAAW;aAaN,SAAS,EAAE,MAAM;IAZlC,SAAgB,MAAM,EAAE,aAAa,CAAC;IACtC,SAAgB,GAAG,EAAE,UAAU,CAAC;IAChC,SAAgB,MAAM,EAAE,aAAa,CAAC;IACtC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,UAAU,CAAC,CAA2B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAA2B;IACjD,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGpB,SAAS,EAAE,MAAM,EACjC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM;IAgCjB;;OAEG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAmBjC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAQ1D;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAK9B;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0D1B;;OAEG;YACW,sBAAsB;IA2BpC;;OAEG;YACW,sBAAsB;IA6CpC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAe/B;;OAEG;IACH,mBAAmB,IAAI,IAAI;CA2C3B"}