naro-mcp 0.6.0 → 0.6.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/dist/index.js +152 -9
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -108,8 +108,149 @@ function controlPlaneUrl(env = process.env) {
|
|
|
108
108
|
|
|
109
109
|
// ../../packages/sdk/src/callback-server.ts
|
|
110
110
|
import { createServer } from "http";
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
|
|
112
|
+
// ../../packages/sdk/src/callback-page.ts
|
|
113
|
+
function escapeHtml(value) {
|
|
114
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
115
|
+
}
|
|
116
|
+
var FAVICON = `data:image/svg+xml,${encodeURIComponent(
|
|
117
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#ededed"/><text x="16" y="23" text-anchor="middle" fill="#000" font-family="system-ui,sans-serif" font-size="20" font-weight="700">n</text></svg>'
|
|
118
|
+
)}`;
|
|
119
|
+
var CHECK_ICON = '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12.5 10 17.5 19 7.5" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
120
|
+
var CROSS_ICON = '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M7 7 17 17M17 7 7 17" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
121
|
+
var STYLES = `
|
|
122
|
+
*{box-sizing:border-box}
|
|
123
|
+
:root{
|
|
124
|
+
--bg:#000;--surface:#0a0a0a;--surface-2:#111;--border:#232323;
|
|
125
|
+
--text:#ededed;--muted:#a1a1a1;--faint:#6f6f6f;
|
|
126
|
+
--sans:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
|
|
127
|
+
--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
|
|
128
|
+
}
|
|
129
|
+
html{color-scheme:dark;-webkit-font-smoothing:antialiased}
|
|
130
|
+
body{
|
|
131
|
+
margin:0;min-height:100vh;display:grid;place-items:center;padding:24px;
|
|
132
|
+
background:var(--bg);color:var(--text);font-family:var(--sans);
|
|
133
|
+
font-size:14px;line-height:1.5;letter-spacing:-.006em;
|
|
134
|
+
}
|
|
135
|
+
body::before{
|
|
136
|
+
content:"";position:fixed;inset:0;pointer-events:none;
|
|
137
|
+
background:radial-gradient(62% 46% at 50% 0%,var(--glow),transparent 72%);
|
|
138
|
+
}
|
|
139
|
+
.card{
|
|
140
|
+
position:relative;width:100%;max-width:400px;padding:34px 32px 28px;
|
|
141
|
+
background:var(--surface);border:1px solid var(--border);border-radius:14px;
|
|
142
|
+
text-align:center;animation:rise .4s cubic-bezier(.2,.7,.3,1) both;
|
|
143
|
+
}
|
|
144
|
+
.brand{
|
|
145
|
+
display:inline-flex;align-items:center;gap:8px;
|
|
146
|
+
font-size:14px;font-weight:600;letter-spacing:-.02em;color:var(--muted);
|
|
147
|
+
}
|
|
148
|
+
.brand-mark{
|
|
149
|
+
display:inline-grid;width:22px;height:22px;place-items:center;
|
|
150
|
+
background:var(--text);color:#000;border-radius:6px;
|
|
151
|
+
font-size:12px;font-weight:700;line-height:1;
|
|
152
|
+
}
|
|
153
|
+
.glyph{
|
|
154
|
+
width:52px;height:52px;margin:26px auto 20px;display:grid;place-items:center;
|
|
155
|
+
border-radius:50%;color:var(--tone);
|
|
156
|
+
background:var(--tone-soft);border:1px solid var(--tone-edge);
|
|
157
|
+
}
|
|
158
|
+
.glyph svg{width:26px;height:26px}
|
|
159
|
+
.glyph path{stroke-dasharray:32;stroke-dashoffset:32;animation:draw .5s .15s cubic-bezier(.2,.7,.3,1) forwards}
|
|
160
|
+
h1{margin:0 0 8px;font-size:19px;font-weight:600;letter-spacing:-.02em}
|
|
161
|
+
p{margin:0 auto;max-width:32ch;color:var(--muted)}
|
|
162
|
+
.detail{
|
|
163
|
+
margin-top:18px;padding:10px 12px;text-align:left;word-break:break-word;
|
|
164
|
+
background:var(--surface-2);border:1px solid var(--border);border-radius:8px;
|
|
165
|
+
font-family:var(--mono);font-size:12.5px;color:var(--muted);
|
|
166
|
+
}
|
|
167
|
+
.hint{
|
|
168
|
+
display:flex;align-items:center;gap:10px;margin-top:22px;padding:10px 12px;
|
|
169
|
+
background:var(--surface-2);border:1px solid var(--border);border-radius:8px;text-align:left;
|
|
170
|
+
}
|
|
171
|
+
.hint-label{
|
|
172
|
+
flex:none;font-size:10px;font-weight:600;letter-spacing:.09em;color:var(--faint);
|
|
173
|
+
}
|
|
174
|
+
.hint code{font-family:var(--mono);font-size:13px;color:var(--text)}
|
|
175
|
+
.hint code::before{content:"$ ";color:var(--faint)}
|
|
176
|
+
footer{margin-top:20px;font-size:12.5px;color:var(--faint)}
|
|
177
|
+
@keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
|
178
|
+
@keyframes draw{to{stroke-dashoffset:0}}
|
|
179
|
+
@media (prefers-reduced-motion:reduce){
|
|
180
|
+
.card{animation:none}
|
|
181
|
+
.glyph path{animation:none;stroke-dashoffset:0}
|
|
182
|
+
}
|
|
183
|
+
`;
|
|
184
|
+
var TONES = {
|
|
185
|
+
success: {
|
|
186
|
+
color: "#4ade80",
|
|
187
|
+
soft: "rgba(74,222,128,.12)",
|
|
188
|
+
edge: "rgba(74,222,128,.3)",
|
|
189
|
+
glow: "rgba(74,222,128,.09)",
|
|
190
|
+
icon: CHECK_ICON
|
|
191
|
+
},
|
|
192
|
+
failure: {
|
|
193
|
+
color: "#ff5c5c",
|
|
194
|
+
soft: "rgba(255,92,92,.12)",
|
|
195
|
+
edge: "rgba(255,92,92,.3)",
|
|
196
|
+
glow: "rgba(255,92,92,.09)",
|
|
197
|
+
icon: CROSS_ICON
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
function page(options) {
|
|
201
|
+
const tone = TONES[options.tone];
|
|
202
|
+
const title = escapeHtml(options.title);
|
|
203
|
+
const detail = options.detail ? `<div class="detail">${escapeHtml(options.detail)}</div>` : "";
|
|
204
|
+
return `<!doctype html>
|
|
205
|
+
<html lang="en">
|
|
206
|
+
<head>
|
|
207
|
+
<meta charset="utf-8">
|
|
208
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
209
|
+
<title>${title} \xB7 naro</title>
|
|
210
|
+
<link rel="icon" href="${FAVICON}">
|
|
211
|
+
<style>:root{--tone:${tone.color};--tone-soft:${tone.soft};--tone-edge:${tone.edge};--glow:${tone.glow}}${STYLES}</style>
|
|
212
|
+
</head>
|
|
213
|
+
<body>
|
|
214
|
+
<main class="card">
|
|
215
|
+
<span class="brand"><span class="brand-mark">n</span>naro</span>
|
|
216
|
+
<div class="glyph">${tone.icon}</div>
|
|
217
|
+
<h1>${title}</h1>
|
|
218
|
+
<p>${escapeHtml(options.message)}</p>
|
|
219
|
+
${detail}
|
|
220
|
+
<div class="hint">
|
|
221
|
+
<span class="hint-label">${escapeHtml(options.hint.label)}</span>
|
|
222
|
+
<code>${escapeHtml(options.hint.command)}</code>
|
|
223
|
+
</div>
|
|
224
|
+
<footer>You can close this tab.</footer>
|
|
225
|
+
</main>
|
|
226
|
+
</body>
|
|
227
|
+
</html>`;
|
|
228
|
+
}
|
|
229
|
+
function successPage() {
|
|
230
|
+
return page({
|
|
231
|
+
tone: "success",
|
|
232
|
+
title: "You're signed in",
|
|
233
|
+
message: "The CLI saved your session. Head back to the terminal to keep going.",
|
|
234
|
+
hint: { label: "NEXT", command: "naro deploy" }
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function failurePage(reason) {
|
|
238
|
+
return page({
|
|
239
|
+
tone: "failure",
|
|
240
|
+
title: "Sign-in failed",
|
|
241
|
+
message: "Nothing was saved. Return to the terminal and try again.",
|
|
242
|
+
detail: reason,
|
|
243
|
+
hint: { label: "RETRY", command: "naro login" }
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ../../packages/sdk/src/callback-server.ts
|
|
248
|
+
function sendPage(res, status, html) {
|
|
249
|
+
res.statusCode = status;
|
|
250
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
251
|
+
res.setHeader("cache-control", "no-store");
|
|
252
|
+
res.end(html);
|
|
253
|
+
}
|
|
113
254
|
async function startCallbackServer() {
|
|
114
255
|
let resolveCode;
|
|
115
256
|
let rejectCode;
|
|
@@ -127,18 +268,20 @@ async function startCallbackServer() {
|
|
|
127
268
|
const error51 = url2.searchParams.get("error");
|
|
128
269
|
const code = url2.searchParams.get("code");
|
|
129
270
|
if (error51) {
|
|
130
|
-
|
|
131
|
-
res
|
|
271
|
+
const description = url2.searchParams.get("error_description");
|
|
272
|
+
sendPage(res, 200, failurePage(description ?? error51));
|
|
132
273
|
rejectCode(new Error(`GitHub authorization failed: ${error51}`));
|
|
133
274
|
return;
|
|
134
275
|
}
|
|
135
276
|
if (!code) {
|
|
136
|
-
|
|
137
|
-
|
|
277
|
+
sendPage(
|
|
278
|
+
res,
|
|
279
|
+
400,
|
|
280
|
+
failurePage("The callback carried no authorization code.")
|
|
281
|
+
);
|
|
138
282
|
return;
|
|
139
283
|
}
|
|
140
|
-
res
|
|
141
|
-
res.end(DONE_HTML);
|
|
284
|
+
sendPage(res, 200, successPage());
|
|
142
285
|
resolveCode(code);
|
|
143
286
|
});
|
|
144
287
|
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
@@ -16059,7 +16202,7 @@ function toolErrorJson(error51) {
|
|
|
16059
16202
|
// src/server.ts
|
|
16060
16203
|
function createServer2(deps) {
|
|
16061
16204
|
const server = new Server(
|
|
16062
|
-
{ name: "naro", version: "0.6.
|
|
16205
|
+
{ name: "naro", version: "0.6.1" },
|
|
16063
16206
|
{ capabilities: { tools: {} } }
|
|
16064
16207
|
);
|
|
16065
16208
|
server.setRequestHandler(ListToolsRequestSchema, () => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naro-mcp",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"naro-mcp": "./dist/index.js"
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
17
17
|
"@supabase/supabase-js": "2.112.3",
|
|
18
|
-
"naro-cli": "0.6.
|
|
18
|
+
"naro-cli": "0.6.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"tsup": "8.5.0",
|
|
22
22
|
"tsx": "4.23.12",
|
|
23
23
|
"typescript": "7.0.2",
|
|
24
24
|
"vitest": "3.2.7",
|
|
25
|
-
"@next-deploy/
|
|
26
|
-
"@next-deploy/
|
|
25
|
+
"@next-deploy/config": "0.1.0",
|
|
26
|
+
"@next-deploy/sdk": "0.1.0"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build": "tsup",
|