neuro-canvas-lms 2.10.0 → 2.10.1

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/installer/cli.mjs CHANGED
@@ -30,6 +30,9 @@ import {
30
30
  isYes,
31
31
  needsSubdomain,
32
32
  subdomainLink,
33
+ isWarmingUp,
34
+ CHECK_WAIT,
35
+ WARMUP_WAIT,
33
36
  } from './lib.mjs';
34
37
  import { msg } from './messages.mjs';
35
38
 
@@ -229,20 +232,34 @@ async function runningVersion(url) {
229
232
 
230
233
  async function healthCheck(url) {
231
234
  let detail = 'no answer';
232
- for (let i = 0; i < 20; i++) {
235
+ let told = false;
236
+ const start = Date.now();
237
+ for (let i = 0; Date.now() - start < (isWarmingUp(detail) ? WARMUP_WAIT : CHECK_WAIT); i++) {
233
238
  if (i) await new Promise(r => setTimeout(r, 3000));
234
239
  try {
235
- const h = await fetch(`${url}/healthz`, { headers: { 'Cache-Control': 'no-cache' } });
240
+ const h = await fetch(`${url}/healthz`, {
241
+ headers: { 'Cache-Control': 'no-cache' },
242
+ signal: AbortSignal.timeout(10000),
243
+ });
236
244
  const j = h.ok ? await h.json() : null;
237
245
  if (!j?.ok) detail = `/healthz HTTP ${h.status}`;
238
246
  else if (j.version !== VERSION) detail = `still ${j.version}`;
239
247
  else {
240
- const mcp = await fetch(`${url}/mcp`, { method: 'POST', body: '{}' });
248
+ const mcp = await fetch(`${url}/mcp`, {
249
+ method: 'POST',
250
+ body: '{}',
251
+ signal: AbortSignal.timeout(10000),
252
+ });
241
253
  if (mcp.status === 401) return { ok: true, connected: j.connected === true };
242
254
  detail = `/mcp HTTP ${mcp.status}`;
243
255
  }
244
256
  } catch (e) {
245
- detail = e.message;
257
+ // fetch says only "fetch failed"; the cause names the real problem (TLS, DNS, …)
258
+ detail = e.cause?.code ?? e.cause?.message ?? e.message;
259
+ if (isWarmingUp(detail) && !told) {
260
+ say('cert_wait');
261
+ told = true;
262
+ }
246
263
  }
247
264
  }
248
265
  return { ok: false, detail };
package/installer/lib.mjs CHANGED
@@ -108,3 +108,12 @@ export const isYes = answer => /^(?:y|yes)$/i.test(String(answer ?? '').trim());
108
108
  export const needsSubdomain = out => /register a workers\.dev subdomain/i.test(out ?? '');
109
109
  export const subdomainLink = accountId =>
110
110
  `https://dash.cloudflare.com/${encodeURIComponent(accountId)}/workers/onboarding`;
111
+
112
+ // A new workers.dev address answers only once its DNS and HTTPS certificate are ready, which can
113
+ // take minutes on a brand-new subdomain. These errors mean "not ready yet", not "broken".
114
+ export const isWarmingUp = detail =>
115
+ /SSL|TLS|CERT|UNABLE_TO_VERIFY|SELF_SIGNED|EPROTO|handshake|ENOTFOUND|EAI_AGAIN|ECONNRESET|ECONNREFUSED|certificate/i.test(
116
+ detail ?? '',
117
+ );
118
+ export const CHECK_WAIT = 60 * 1000; // a normal deploy answers within a minute
119
+ export const WARMUP_WAIT = 5 * 60 * 1000; // a new address may need a few minutes for its certificate
@@ -47,6 +47,8 @@ const M = {
47
47
  un_done:
48
48
  'Removed. Also delete the Canvas token (Canvas → Account → Settings) and the connector in your AI app.',
49
49
  cancelled: 'Cancelled.',
50
+ cert_wait:
51
+ 'The new workers.dev address is still getting its HTTPS certificate. The first time this can take a few minutes; waiting…',
50
52
  pick_account_flag:
51
53
  'This Cloudflare login has several accounts. Run the same command again with one of these added:\n{list}',
52
54
  canvas_flag:
@@ -105,6 +107,7 @@ const M = {
105
107
  un_failed: '没能删除{what}:{detail}\n 本地安装记录已保留,再运行一次同一条命令即可重试。',
106
108
  un_done: '已删除。另外请删掉 Canvas 令牌(Canvas → 账户 → 设置)和 AI 应用里的连接器。',
107
109
  cancelled: '已取消。',
110
+ cert_wait: '新的 workers.dev 地址还在申请 HTTPS 证书,第一次可能要几分钟,正在等待…',
108
111
  pick_account_flag:
109
112
  '这个 Cloudflare 登录下有多个账号。请在同一条命令后加上其中一个,再运行一次:\n{list}',
110
113
  canvas_flag:
@@ -172,6 +175,8 @@ const M = {
172
175
  un_done:
173
176
  'Eliminado. Borra también el token de Canvas (Canvas → Cuenta → Configuración) y el conector en tu app de IA.',
174
177
  cancelled: 'Cancelado.',
178
+ cert_wait:
179
+ 'La nueva dirección workers.dev todavía está obteniendo su certificado HTTPS. La primera vez puede tardar unos minutos; esperando…',
175
180
  pick_account_flag:
176
181
  'Este inicio de sesión de Cloudflare tiene varias cuentas. Ejecuta el mismo comando otra vez añadiendo una de estas:\n{list}',
177
182
  canvas_flag:
@@ -239,6 +244,8 @@ const M = {
239
244
  un_done:
240
245
  '削除しました。Canvas トークン(Canvas → アカウント → 設定)と AI アプリのコネクタも削除してください。',
241
246
  cancelled: 'キャンセルしました。',
247
+ cert_wait:
248
+ '新しい workers.dev アドレスの HTTPS 証明書を準備しています。初回は数分かかることがあります。待機しています…',
242
249
  pick_account_flag:
243
250
  'この Cloudflare ログインには複数のアカウントがあります。同じコマンドに次のどれかを付けて、もう一度実行してください:\n{list}',
244
251
  canvas_flag:
@@ -306,6 +313,8 @@ const M = {
306
313
  un_done:
307
314
  'हटा दिया गया। Canvas टोकन (Canvas → Account → Settings) और अपने AI ऐप में कनेक्टर भी हटाएँ।',
308
315
  cancelled: 'रद्द किया गया।',
316
+ cert_wait:
317
+ 'नए workers.dev पते का HTTPS प्रमाणपत्र अभी तैयार हो रहा है। पहली बार इसमें कुछ मिनट लग सकते हैं; प्रतीक्षा हो रही है…',
309
318
  pick_account_flag:
310
319
  'इस Cloudflare लॉगिन में कई खाते हैं। वही कमांड इनमें से एक जोड़कर फिर से चलाएँ:\n{list}',
311
320
  canvas_flag:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neuro-canvas-lms",
3
- "version": "2.10.0",
3
+ "version": "2.10.1",
4
4
  "description": "Neuro-CanvasLMS: read-only connector that lets Claude or ChatGPT read any Canvas LMS (remote MCP server on your own Cloudflare account)",
5
5
  "keywords": [
6
6
  "canvas",
package/version.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  // The connector's version, shown on its home page and at /healthz (the installer checks that the
2
2
  // deployed version answers). Bump it together with package.json when something changes.
3
- export const VERSION = '2.10.0';
3
+ export const VERSION = '2.10.1';