replicas-engine 0.1.599 → 0.1.602

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/src/index.js CHANGED
@@ -484,9 +484,12 @@ function isCanvasTextKind(kind) {
484
484
  return kind === "markdown" || kind === "mermaid" || kind === "html" || kind === "text";
485
485
  }
486
486
  function sanitizeCanvasFilename(filename) {
487
- const safe = filename.split(/[\\/]/).pop() ?? "";
488
- if (!safe || safe !== filename || safe.startsWith(".")) return null;
489
- return safe;
487
+ if (filename.includes("\\")) return null;
488
+ const segments = filename.split("/");
489
+ if (segments.some((segment) => !segment || segment === "." || segment === ".." || segment.startsWith("."))) {
490
+ return null;
491
+ }
492
+ return filename;
490
493
  }
491
494
  function bytesToBase64(bytes) {
492
495
  let binary = "";
@@ -10669,7 +10672,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10669
10672
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10670
10673
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10671
10674
  var codexCliVersionEnsured = null;
10672
- var ENGINE_PACKAGE_VERSION = "0.1.599";
10675
+ var ENGINE_PACKAGE_VERSION = "0.1.602";
10673
10676
  var INITIALIZE_METHOD = "initialize";
10674
10677
  var INITIALIZED_NOTIFICATION = "initialized";
10675
10678
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -15267,28 +15270,42 @@ async function canvasDirectories() {
15267
15270
  ];
15268
15271
  }
15269
15272
  var CanvasService = class {
15273
+ constructor(directories = canvasDirectories) {
15274
+ this.directories = directories;
15275
+ }
15276
+ directories;
15270
15277
  async listItems() {
15271
15278
  const items = /* @__PURE__ */ new Map();
15272
- for (const directory of await canvasDirectories()) {
15273
- let entries;
15274
- try {
15275
- entries = await readdir7(directory, { withFileTypes: true });
15276
- } catch {
15277
- continue;
15278
- }
15279
- for (const entry of entries) {
15280
- if (!entry.isFile()) continue;
15281
- if (entry.name.startsWith(".")) continue;
15282
- if (items.has(entry.name)) continue;
15283
- const { kind } = classifyCanvasFilename(entry.name);
15284
- let sizeBytes = 0;
15279
+ for (const directory of await this.directories()) {
15280
+ const pending = [{ directory, relativePath: "" }];
15281
+ while (pending.length > 0) {
15282
+ const current = pending.pop();
15283
+ if (!current) continue;
15284
+ let entries;
15285
15285
  try {
15286
- const s = await stat3(join23(directory, entry.name));
15287
- sizeBytes = s.size;
15286
+ entries = await readdir7(current.directory, { withFileTypes: true });
15288
15287
  } catch {
15289
15288
  continue;
15290
15289
  }
15291
- items.set(entry.name, { filename: entry.name, kind, sizeBytes });
15290
+ for (const entry of entries) {
15291
+ if (entry.name.startsWith(".")) continue;
15292
+ const filename = current.relativePath ? `${current.relativePath}/${entry.name}` : entry.name;
15293
+ const filePath = join23(current.directory, entry.name);
15294
+ if (entry.isDirectory()) {
15295
+ pending.push({ directory: filePath, relativePath: filename });
15296
+ continue;
15297
+ }
15298
+ if (!entry.isFile() || items.has(filename)) continue;
15299
+ const { kind } = classifyCanvasFilename(filename);
15300
+ let sizeBytes = 0;
15301
+ try {
15302
+ const s = await stat3(filePath);
15303
+ sizeBytes = s.size;
15304
+ } catch {
15305
+ continue;
15306
+ }
15307
+ items.set(filename, { filename, kind, sizeBytes });
15308
+ }
15292
15309
  }
15293
15310
  }
15294
15311
  return Array.from(items.values()).sort((a, b) => a.filename.localeCompare(b.filename));
@@ -15297,7 +15314,7 @@ var CanvasService = class {
15297
15314
  const safe = sanitizeCanvasFilename(filename);
15298
15315
  if (!safe) return null;
15299
15316
  const { kind, mimeType } = classifyCanvasFilename(safe);
15300
- for (const directory of await canvasDirectories()) {
15317
+ for (const directory of await this.directories()) {
15301
15318
  const filePath = join23(directory, safe);
15302
15319
  let sizeBytes = 0;
15303
15320
  let updatedAt = "";
@@ -18010,7 +18027,7 @@ data: ${JSON.stringify("Terminal session not found")}
18010
18027
  });
18011
18028
  app2.get("/canvas", async (c) => {
18012
18029
  try {
18013
- const items = await canvasService.listItems();
18030
+ const items = await deps.canvasService.listItems();
18014
18031
  return c.json({ items });
18015
18032
  } catch (error) {
18016
18033
  return c.json(
@@ -18019,13 +18036,13 @@ data: ${JSON.stringify("Terminal session not found")}
18019
18036
  );
18020
18037
  }
18021
18038
  });
18022
- app2.get("/canvas/:filename", async (c) => {
18039
+ app2.get("/canvas/:filename{.+}", async (c) => {
18023
18040
  try {
18024
18041
  const filename = c.req.param("filename");
18025
18042
  if (!filename) {
18026
18043
  return c.json(jsonError("Filename required"), 400);
18027
18044
  }
18028
- const item = await canvasService.getItem(filename);
18045
+ const item = await deps.canvasService.getItem(filename);
18029
18046
  if (!item) {
18030
18047
  return c.json(jsonError("Canvas item not found"), 404);
18031
18048
  }
@@ -18658,7 +18675,7 @@ app.post(GITLAB_CREDENTIAL_REFRESH_PATH, async (c) => {
18658
18675
  return c.body(null, 204);
18659
18676
  });
18660
18677
  var repoFileService = new RepoFileService(gitService);
18661
- app.route("/", createV1Routes({ chatService, repoFileService }));
18678
+ app.route("/", createV1Routes({ chatService, repoFileService, canvasService }));
18662
18679
  var port = ENGINE_ENV.REPLICAS_ENGINE_PORT;
18663
18680
  function startStatusBroadcaster() {
18664
18681
  let previousRepoStatus = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.599",
3
+ "version": "0.1.602",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -4,78 +4,105 @@ export declare const PLUGIN_CATALOG: readonly [{
4
4
  readonly id: "attio";
5
5
  readonly toolkit: "attio";
6
6
  readonly authType: "oauth";
7
+ readonly category: "business";
7
8
  readonly name: "Attio";
8
9
  readonly description: "Search CRM records, people, companies, lists, and notes.";
9
10
  }, {
10
11
  readonly id: "clickhouse";
11
12
  readonly toolkit: "clickhouse";
12
13
  readonly authType: "basic";
14
+ readonly category: "data";
13
15
  readonly name: "ClickHouse";
14
16
  readonly description: "Inspect databases, tables, schemas, and query results.";
15
17
  }, {
16
18
  readonly id: "cloudflare";
17
19
  readonly toolkit: "cloudflare_api_key";
18
20
  readonly authType: "api_key";
21
+ readonly category: "data";
19
22
  readonly name: "Cloudflare";
20
23
  readonly description: "Inspect zones, DNS records, analytics, and security settings.";
24
+ }, {
25
+ readonly id: "gmail";
26
+ readonly toolkit: "gmail";
27
+ readonly authType: "oauth";
28
+ readonly category: "productivity";
29
+ readonly name: "Gmail";
30
+ readonly description: "Read messages, threads, attachments, labels, and mailbox metadata.";
21
31
  }, {
22
32
  readonly id: "googleads";
23
33
  readonly toolkit: "googleads";
24
34
  readonly authType: "oauth";
35
+ readonly category: "data";
25
36
  readonly name: "Google Ads";
26
37
  readonly description: "Inspect campaigns, customers, accounts, and reporting data.";
27
38
  }, {
28
39
  readonly id: "googledocs";
29
40
  readonly toolkit: "googledocs";
30
41
  readonly authType: "oauth";
42
+ readonly category: "productivity";
31
43
  readonly name: "Google Docs";
32
44
  readonly description: "Read documents, structure, comments, and exported content.";
33
45
  }, {
34
46
  readonly id: "googledrive";
35
47
  readonly toolkit: "googledrive";
36
48
  readonly authType: "oauth";
49
+ readonly category: "productivity";
37
50
  readonly name: "Google Drive";
38
51
  readonly description: "Search files, folders, metadata, permissions, and shared drives.";
39
52
  }, {
40
53
  readonly id: "googlesearch";
41
54
  readonly toolkit: "google_search_console";
42
55
  readonly authType: "oauth";
56
+ readonly category: "data";
43
57
  readonly name: "Google Search";
44
58
  readonly description: "Inspect Search Console performance, indexing, sites, and sitemaps.";
45
59
  }, {
46
60
  readonly id: "googlesheets";
47
61
  readonly toolkit: "googlesheets";
48
62
  readonly authType: "oauth";
63
+ readonly category: "productivity";
49
64
  readonly name: "Google Sheets";
50
65
  readonly description: "Read spreadsheets, worksheets, ranges, tables, and charts.";
51
66
  }, {
52
67
  readonly id: "linkedin";
53
68
  readonly toolkit: "linkedin";
54
69
  readonly authType: "oauth";
70
+ readonly category: "business";
55
71
  readonly name: "LinkedIn";
56
72
  readonly description: "Inspect profiles, organizations, posts, and professional activity.";
57
73
  }, {
58
74
  readonly id: "posthog";
59
75
  readonly toolkit: "posthog";
60
76
  readonly authType: "api_key";
77
+ readonly category: "data";
61
78
  readonly name: "PostHog";
62
79
  readonly description: "Inspect projects, events, insights, dashboards, flags, and recordings.";
63
80
  }, {
64
81
  readonly id: "stripe";
65
82
  readonly toolkit: "stripe";
66
83
  readonly authType: "oauth";
84
+ readonly category: "business";
67
85
  readonly name: "Stripe";
68
86
  readonly description: "Inspect customers, payments, invoices, subscriptions, and balances.";
87
+ }, {
88
+ readonly id: "vercel";
89
+ readonly toolkit: "vercel";
90
+ readonly authType: "api_key";
91
+ readonly category: "data";
92
+ readonly name: "Vercel";
93
+ readonly description: "Inspect projects, deployments, logs, domains, and infrastructure.";
69
94
  }];
70
95
  export type PluginId = (typeof PLUGIN_CATALOG)[number]['id'];
71
96
  export type PluginScope = 'organization' | 'personal';
72
97
  export type PluginAuthType = (typeof PLUGIN_CATALOG)[number]['authType'];
98
+ export type PluginCategory = (typeof PLUGIN_CATALOG)[number]['category'];
73
99
  export declare const PLUGIN_CONNECTION_STATUSES: readonly ["initiated", "active", "expired", "failed"];
74
100
  export type PluginConnectionStatus = (typeof PLUGIN_CONNECTION_STATUSES)[number];
75
101
  export interface PluginCatalogItem {
76
102
  id: PluginId;
77
103
  toolkit: string;
78
104
  authType: PluginAuthType;
105
+ category: PluginCategory;
79
106
  name: string;
80
107
  description: string;
81
108
  }
@@ -107,10 +134,11 @@ export interface PluginConnectClickHouseRequest {
107
134
  password: string;
108
135
  database?: string;
109
136
  }
110
- export interface PluginConnectCloudflareRequest {
137
+ export interface PluginConnectApiKeyRequest {
111
138
  apiKey: string;
112
139
  }
113
- export type PluginConnectRequest = PluginConnectPostHogRequest | PluginConnectClickHouseRequest | PluginConnectCloudflareRequest;
140
+ export type PluginConnectCloudflareRequest = PluginConnectApiKeyRequest;
141
+ export type PluginConnectRequest = PluginConnectPostHogRequest | PluginConnectClickHouseRequest | PluginConnectApiKeyRequest;
114
142
  export interface PluginConnectResponse {
115
143
  success: true;
116
144
  }