neon 8.12.2 → 8.13.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/README.md +1 -1
- package/dist/_chunks/{checkout-BGvlLc43.js → checkout-CXIOydqZ.js} +3 -3
- package/dist/_chunks/{claim-DqzLXZMN.js → claim-DqAvAvDm.js} +1 -1
- package/dist/_chunks/{config-BnwcGpbq.js → config-BH_qRHiG.js} +1 -1
- package/dist/_chunks/{deploy-BCVcDR1O.js → deploy-D7B0Xfjg.js} +1 -1
- package/dist/_chunks/{dev-mrJKMt2R.js → dev-CSvxAecE.js} +3 -3
- package/dist/_chunks/{git-pN4kMH0d.js → git-H32TNt6M.js} +2 -2
- package/dist/_chunks/{link-DOM84hYj.js → link-BgtkOBws.js} +2 -2
- package/dist/_chunks/{neon_auth-CBs1_3qu.js → neon_auth-DpF83S24.js} +440 -2
- package/dist/_chunks/{status-DoNjIbKf.js → status-DV8Z2kw3.js} +1 -1
- package/dist/api.js +63 -0
- package/dist/commands/checkout.js +1 -1
- package/dist/commands/claim.js +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/env.js +1 -1
- package/dist/commands/functions_new.js +1 -1
- package/dist/commands/git.js +1 -1
- package/dist/commands/index.js +10 -10
- package/dist/commands/link.js +1 -1
- package/dist/commands/neon_auth.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/subscribe.js +1 -1
- package/dist/init/auth.js +1 -1
- package/dist/init/link.js +1 -1
- package/dist/init/run.js +3 -3
- package/dist/skills/freshness.js +61 -11
- package/dist/skills/run.js +4 -2
- package/dist/test_utils/fixtures.js +4 -3
- package/package.json +8 -8
- package/dist/_chunks/{env-uVRY4xah.js → env-5HS5qQGd.js} +1 -1
package/README.md
CHANGED
|
@@ -955,7 +955,7 @@ The default mints an account-wide API key (or reuses the Bearer already configur
|
|
|
955
955
|
|
|
956
956
|
## Install Neon agent skills (`skills`)
|
|
957
957
|
|
|
958
|
-
`neon skills` installs Neon agent skills by running `npx skills add
|
|
958
|
+
`neon skills` installs Neon agent skills by running `npx skills@latest add`, so it always uses the latest skills CLI, even when an older one is installed globally. It does not call the Neon API. This command needs Node.js 22.20 or newer. The rest of the CLI supports Node.js 20.19 or newer.
|
|
959
959
|
|
|
960
960
|
```bash
|
|
961
961
|
# Interactive: this directory, then agents, then skills.
|
|
@@ -11,9 +11,9 @@ import { looksLikeBranchId } from "../utils/formats.js";
|
|
|
11
11
|
import { fillSingleProject, listAllProjectBranches } from "../utils/enrichers.js";
|
|
12
12
|
import { buildCheckoutEvent, readGitContext } from "../utils/git.js";
|
|
13
13
|
import { buildHookBranch, loadHookConfig, resolveHookEnv, runCheckoutAfterHook, runCheckoutBeforeHook, runCreateAfterHook, runCreateBeforeHook } from "../utils/hooks.js";
|
|
14
|
-
import { n as autoPullEnvAfterPin } from "./env-
|
|
15
|
-
import { a as applyPolicyOnCreate, f as envFlag, l as createBranchFromPolicyOnCheckout } from "./config-
|
|
16
|
-
import { i as handler$1 } from "./link-
|
|
14
|
+
import { n as autoPullEnvAfterPin } from "./env-5HS5qQGd.js";
|
|
15
|
+
import { a as applyPolicyOnCreate, f as envFlag, l as createBranchFromPolicyOnCheckout } from "./config-BH_qRHiG.js";
|
|
16
|
+
import { i as handler$1 } from "./link-BgtkOBws.js";
|
|
17
17
|
import chalk from "chalk";
|
|
18
18
|
import prompts from "prompts";
|
|
19
19
|
//#region src/commands/checkout.ts
|
|
@@ -12,7 +12,7 @@ import { projectConfigPath } from "../project.js";
|
|
|
12
12
|
import { resolveEnvFilePath } from "../env_file.js";
|
|
13
13
|
import { writer } from "../writer.js";
|
|
14
14
|
import { noPassthrough } from "../utils/flags.js";
|
|
15
|
-
import { c as pull } from "./env-
|
|
15
|
+
import { c as pull } from "./env-5HS5qQGd.js";
|
|
16
16
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
17
17
|
import open from "open";
|
|
18
18
|
import prompts from "prompts";
|
|
@@ -23,7 +23,7 @@ import { readGitContext } from "../utils/git.js";
|
|
|
23
23
|
import { resolveHookEnv, runDeployAfterHook, runDeployBeforeHook } from "../utils/hooks.js";
|
|
24
24
|
import { pickServicesInteractively } from "../utils/service_picker.js";
|
|
25
25
|
import { zipBundle } from "../utils/zip.js";
|
|
26
|
-
import { n as autoPullEnvAfterPin } from "./env-
|
|
26
|
+
import { n as autoPullEnvAfterPin } from "./env-5HS5qQGd.js";
|
|
27
27
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
28
28
|
import { dirname, join, relative, resolve } from "node:path";
|
|
29
29
|
import chalk from "chalk";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { fillSingleProject } from "../utils/enrichers.js";
|
|
3
|
-
import { f as envFlag, i as applyFlags, p as envPullFlag, r as applyCmd } from "./config-
|
|
3
|
+
import { f as envFlag, i as applyFlags, p as envPullFlag, r as applyCmd } from "./config-BH_qRHiG.js";
|
|
4
4
|
import { DEPLOY_COMMANDS_EPILOGUE } from "../commands/deploy_help.js";
|
|
5
5
|
//#region src/commands/deploy.ts
|
|
6
6
|
var deploy_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -4,12 +4,12 @@ import { isClaimableEnvTarget } from "../claimable/state.js";
|
|
|
4
4
|
import { getCliName } from "../utils/cli_name.js";
|
|
5
5
|
import { defaultDevEnvFiles, readEnvFile, resolveEnvFilePath } from "../env_file.js";
|
|
6
6
|
import { l as functionBaseUrlKey } from "./env-BpP3Dqpe.js";
|
|
7
|
+
import { branchIdResolve } from "../utils/enrichers.js";
|
|
8
|
+
import { bundleEntry } from "../utils/esbuild.js";
|
|
7
9
|
import { a as resolveDevEnv } from "./env-BNm69Qh8.js";
|
|
10
|
+
import { f as envFlag } from "./config-BH_qRHiG.js";
|
|
8
11
|
import { findConfigFunctionBySource, resolveFunctionsFromConfig } from "../dev/functions.js";
|
|
9
12
|
import { resolveWatchInputs } from "../dev/inputs.js";
|
|
10
|
-
import { branchIdResolve } from "../utils/enrichers.js";
|
|
11
|
-
import { bundleEntry } from "../utils/esbuild.js";
|
|
12
|
-
import { f as envFlag } from "./config-BnwcGpbq.js";
|
|
13
13
|
import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
14
14
|
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
@@ -5,8 +5,8 @@ import { CONTEXT_FILE, contextBranch, gitBranchMap, gitBranchMapping, isUnfollow
|
|
|
5
5
|
import { writer } from "../writer.js";
|
|
6
6
|
import { neonSafeBranchName } from "../utils/branch_name.js";
|
|
7
7
|
import { currentGitBranch, gitPull, gitRepoRoot, hasUpstream, installPostCheckoutHook, isGitRepo, isManagedHook, localGitBranches, postCheckoutHookPath, readGitContext, removePostCheckoutHook } from "../utils/git.js";
|
|
8
|
-
import { o as quoteFlagValue } from "./link-
|
|
9
|
-
import { o as handler$1 } from "./checkout-
|
|
8
|
+
import { o as quoteFlagValue } from "./link-BgtkOBws.js";
|
|
9
|
+
import { o as handler$1 } from "./checkout-CXIOydqZ.js";
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import chalk from "chalk";
|
|
@@ -13,8 +13,8 @@ import { writer } from "../writer.js";
|
|
|
13
13
|
import { createBranch, pickBranchInteractively } from "../utils/branch_picker.js";
|
|
14
14
|
import { looksLikeBranchId } from "../utils/formats.js";
|
|
15
15
|
import { listAllProjectBranches } from "../utils/enrichers.js";
|
|
16
|
-
import { n as autoPullEnvAfterPin } from "./env-
|
|
17
|
-
import { h as initCmd } from "./config-
|
|
16
|
+
import { n as autoPullEnvAfterPin } from "./env-5HS5qQGd.js";
|
|
17
|
+
import { h as initCmd } from "./config-BH_qRHiG.js";
|
|
18
18
|
import { formatLinkSummary } from "../commands/link_output.js";
|
|
19
19
|
import { r as REGIONS } from "./projects-BwI2Uo0z.js";
|
|
20
20
|
import prompts from "prompts";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
+
import { log } from "../log.js";
|
|
2
3
|
import { codeFromBody, isNeonApiError, retryOnLock } from "../api.js";
|
|
3
4
|
import { stripAnsi } from "../human_table.js";
|
|
4
5
|
import { writer } from "../writer.js";
|
|
@@ -78,6 +79,24 @@ const ORGANIZATION_FIELDS = [
|
|
|
78
79
|
"organization_limit",
|
|
79
80
|
"creator_role"
|
|
80
81
|
];
|
|
82
|
+
const OAUTH_SERVER_FIELDS = [
|
|
83
|
+
"enabled",
|
|
84
|
+
"login_page",
|
|
85
|
+
"consent_page",
|
|
86
|
+
"mcp",
|
|
87
|
+
"resources"
|
|
88
|
+
];
|
|
89
|
+
const OAUTH_CLIENT_FIELDS = [
|
|
90
|
+
"client_id",
|
|
91
|
+
"name",
|
|
92
|
+
"type",
|
|
93
|
+
"redirect_uris",
|
|
94
|
+
"resources",
|
|
95
|
+
"skip_consent",
|
|
96
|
+
"disabled",
|
|
97
|
+
"created_at"
|
|
98
|
+
];
|
|
99
|
+
const OAUTH_CLIENT_SECRET_FIELDS = ["client_id", "client_secret"];
|
|
81
100
|
const WEBHOOK_FIELDS = [
|
|
82
101
|
"enabled",
|
|
83
102
|
"webhook_url",
|
|
@@ -110,7 +129,7 @@ const builder = (argv) => {
|
|
|
110
129
|
default: false
|
|
111
130
|
} }), async (args) => {
|
|
112
131
|
await disable(args);
|
|
113
|
-
}).command("oauth-provider",
|
|
132
|
+
}).command("oauth-provider", `Manage social login providers (${SUPPORTED_OAUTH_PROVIDERS.join(", ")})`, (yargs) => {
|
|
114
133
|
return yargs.usage("$0 neon-auth oauth-provider <sub-command> [options]").command("list", "List OAuth providers", (yargs) => yargs, async (args) => {
|
|
115
134
|
await oauthProviderList(args);
|
|
116
135
|
}).command("add", "Add an OAuth provider", (yargs) => yargs.options({
|
|
@@ -155,6 +174,87 @@ const builder = (argv) => {
|
|
|
155
174
|
} }), async (args) => {
|
|
156
175
|
await oauthProviderDelete(args);
|
|
157
176
|
});
|
|
177
|
+
}).command("oauth-client", "Manage clients of this Neon Auth OAuth server (e.g. MCP clients); configure the server with `config oauth-server`", (yargs) => {
|
|
178
|
+
return yargs.usage("$0 neon-auth oauth-client <sub-command> [options]").command("list", "List OAuth clients", (yargs) => yargs, async (args) => {
|
|
179
|
+
await oauthClientList(args);
|
|
180
|
+
}).command("create", "Create an OAuth client", (yargs) => yargs.options({
|
|
181
|
+
name: {
|
|
182
|
+
describe: "Display name of the client",
|
|
183
|
+
type: "string",
|
|
184
|
+
demandOption: true
|
|
185
|
+
},
|
|
186
|
+
type: {
|
|
187
|
+
describe: "Client type. Confidential clients receive a secret that is shown only once",
|
|
188
|
+
type: "string",
|
|
189
|
+
choices: ["confidential", "public"],
|
|
190
|
+
demandOption: true
|
|
191
|
+
},
|
|
192
|
+
"redirect-uris": {
|
|
193
|
+
describe: "Redirect URIs the client may use (https, or http on loopback when localhost is allowed)",
|
|
194
|
+
type: "string",
|
|
195
|
+
array: true,
|
|
196
|
+
demandOption: true
|
|
197
|
+
},
|
|
198
|
+
resources: {
|
|
199
|
+
describe: "Protected resource URLs to link the client to; each must be configured with `neon-auth config oauth-server resource add`",
|
|
200
|
+
type: "string",
|
|
201
|
+
array: true,
|
|
202
|
+
demandOption: true
|
|
203
|
+
},
|
|
204
|
+
"skip-consent": {
|
|
205
|
+
describe: "Skip the consent prompt (first-party clients only)",
|
|
206
|
+
type: "boolean"
|
|
207
|
+
}
|
|
208
|
+
}).example("$0 neon-auth oauth-client create --name 'My app' --type confidential --redirect-uris https://app.example.com/callback --resources https://api.example.com", "Create a confidential client"), async (args) => {
|
|
209
|
+
await oauthClientCreate(args);
|
|
210
|
+
}).command("get <client-id>", "Get an OAuth client", (yargs) => yargs.usage("$0 neon-auth oauth-client get <client-id> [options]").positional("client-id", {
|
|
211
|
+
describe: "OAuth client ID",
|
|
212
|
+
type: "string",
|
|
213
|
+
demandOption: true
|
|
214
|
+
}), async (args) => {
|
|
215
|
+
await oauthClientGet(args);
|
|
216
|
+
}).command("update <client-id>", "Update an OAuth client (the type cannot be changed)", (yargs) => yargs.usage("$0 neon-auth oauth-client update <client-id> [options]").positional("client-id", {
|
|
217
|
+
describe: "OAuth client ID",
|
|
218
|
+
type: "string",
|
|
219
|
+
demandOption: true
|
|
220
|
+
}).options({
|
|
221
|
+
name: {
|
|
222
|
+
describe: "Display name of the client",
|
|
223
|
+
type: "string"
|
|
224
|
+
},
|
|
225
|
+
"redirect-uris": {
|
|
226
|
+
describe: "Redirect URIs the client may use; replaces the stored list",
|
|
227
|
+
type: "string",
|
|
228
|
+
array: true
|
|
229
|
+
},
|
|
230
|
+
resources: {
|
|
231
|
+
describe: "Protected resource URLs to link the client to; replaces the stored list (at least one)",
|
|
232
|
+
type: "string",
|
|
233
|
+
array: true
|
|
234
|
+
},
|
|
235
|
+
"skip-consent": {
|
|
236
|
+
describe: "Skip the consent prompt (first-party clients only). Use --no-skip-consent or --skip-consent false to turn off",
|
|
237
|
+
type: "boolean"
|
|
238
|
+
},
|
|
239
|
+
disabled: {
|
|
240
|
+
describe: "Disable the client. Use --no-disabled or --disabled false to re-enable",
|
|
241
|
+
type: "boolean"
|
|
242
|
+
}
|
|
243
|
+
}), async (args) => {
|
|
244
|
+
await oauthClientUpdate(args);
|
|
245
|
+
}).command("delete <client-id>", "Delete an OAuth client", (yargs) => yargs.usage("$0 neon-auth oauth-client delete <client-id> [options]").positional("client-id", {
|
|
246
|
+
describe: "OAuth client ID",
|
|
247
|
+
type: "string",
|
|
248
|
+
demandOption: true
|
|
249
|
+
}), async (args) => {
|
|
250
|
+
await oauthClientDelete(args);
|
|
251
|
+
}).command("rotate-secret <client-id>", "Rotate the secret of a confidential client; the old secret stops working immediately", (yargs) => yargs.usage("$0 neon-auth oauth-client rotate-secret <client-id> [options]").positional("client-id", {
|
|
252
|
+
describe: "OAuth client ID",
|
|
253
|
+
type: "string",
|
|
254
|
+
demandOption: true
|
|
255
|
+
}), async (args) => {
|
|
256
|
+
await oauthClientRotateSecret(args);
|
|
257
|
+
});
|
|
158
258
|
}).command("domain", "Manage redirect URI trusted domains", (yargs) => {
|
|
159
259
|
return yargs.usage("$0 neon-auth domain <sub-command> [options]").command("list", "List trusted domains", (yargs) => yargs, async (args) => {
|
|
160
260
|
await domainList(args);
|
|
@@ -283,6 +383,63 @@ const builder = (argv) => {
|
|
|
283
383
|
}), async (args) => {
|
|
284
384
|
await organizationUpdate(args);
|
|
285
385
|
});
|
|
386
|
+
}).command("oauth-server", "Manage the OAuth 2.1 authorization server (API plugin: oauth_provider)", (yargs) => {
|
|
387
|
+
return yargs.usage("$0 neon-auth config oauth-server <sub-command> [options]").command("get", "Get OAuth server config", (yargs) => yargs, async (args) => {
|
|
388
|
+
await oauthServerGet(args);
|
|
389
|
+
}).command("update", "Update OAuth server config", (yargs) => yargs.options({
|
|
390
|
+
enabled: {
|
|
391
|
+
describe: "Enable the OAuth server. Use --no-enabled or --enabled false to disable",
|
|
392
|
+
type: "boolean"
|
|
393
|
+
},
|
|
394
|
+
"login-page": {
|
|
395
|
+
describe: "URL of the page authorization requests redirect to for sign-in",
|
|
396
|
+
type: "string"
|
|
397
|
+
},
|
|
398
|
+
"consent-page": {
|
|
399
|
+
describe: "URL of the page authorization requests redirect to for consent",
|
|
400
|
+
type: "string"
|
|
401
|
+
},
|
|
402
|
+
resources: {
|
|
403
|
+
describe: "Protected resource URLs that clients can be linked to; replaces the stored list. Use `resource add|remove` for incremental changes",
|
|
404
|
+
type: "string",
|
|
405
|
+
array: true
|
|
406
|
+
},
|
|
407
|
+
"mcp-resource": {
|
|
408
|
+
describe: "MCP server URL that MCP clients are linked to. Defaults to the stored value when another --mcp-* flag is given. To remove the MCP configuration, use --no-mcp",
|
|
409
|
+
type: "string"
|
|
410
|
+
},
|
|
411
|
+
mcp: {
|
|
412
|
+
describe: "Remove the MCP configuration (only --no-mcp is accepted)",
|
|
413
|
+
type: "boolean"
|
|
414
|
+
},
|
|
415
|
+
"mcp-client-id-metadata-documents": {
|
|
416
|
+
describe: "Allow MCP clients to identify themselves with a Client ID Metadata Document (CIMD) URL. Use --no-mcp-client-id-metadata-documents to disallow",
|
|
417
|
+
type: "boolean"
|
|
418
|
+
},
|
|
419
|
+
"mcp-dynamic-registration": {
|
|
420
|
+
describe: "Allow MCP clients to register themselves via dynamic client registration (deprecated in favor of CIMD)",
|
|
421
|
+
type: "boolean",
|
|
422
|
+
hidden: true
|
|
423
|
+
}
|
|
424
|
+
}).example("$0 neon-auth config oauth-server update --enabled --mcp-resource https://example.com/mcp --mcp-client-id-metadata-documents", "Enable the OAuth server for an MCP server"), async (args) => {
|
|
425
|
+
await oauthServerUpdate(args);
|
|
426
|
+
}).command("resource", "Manage the protected resources of the OAuth server. Add and remove read the stored list and write back the full list, so concurrent changes by others can be overwritten", (yargs) => yargs.usage("$0 neon-auth config oauth-server resource <sub-command> [options]").command("list", "List protected resources", (yargs) => yargs, async (args) => {
|
|
427
|
+
await oauthResourceList(args);
|
|
428
|
+
}).command("add <url...>", "Add protected resources (reads the stored list and writes back the full list; concurrent changes by others can be overwritten)", (yargs) => yargs.positional("url", {
|
|
429
|
+
describe: "Protected resource URLs to add",
|
|
430
|
+
type: "string",
|
|
431
|
+
array: true,
|
|
432
|
+
demandOption: true
|
|
433
|
+
}), async (args) => {
|
|
434
|
+
await oauthResourceAdd(args);
|
|
435
|
+
}).command("remove <url...>", "Remove protected resources (reads the stored list and writes back the full list; concurrent changes by others can be overwritten)", (yargs) => yargs.positional("url", {
|
|
436
|
+
describe: "Protected resource URLs to remove",
|
|
437
|
+
type: "string",
|
|
438
|
+
array: true,
|
|
439
|
+
demandOption: true
|
|
440
|
+
}), async (args) => {
|
|
441
|
+
await oauthResourceRemove(args);
|
|
442
|
+
}));
|
|
286
443
|
}).command("webhook", "Manage webhook configuration", (yargs) => {
|
|
287
444
|
return yargs.usage("$0 neon-auth config webhook <sub-command> [options]").command("get", "Get webhook config", (yargs) => yargs, async (args) => {
|
|
288
445
|
await webhookGet(args);
|
|
@@ -319,7 +476,7 @@ const builder = (argv) => {
|
|
|
319
476
|
return yargs.usage("$0 neon-auth plugins <sub-command> [options]").command("list", "List all plugin configurations", (yargs) => yargs, async (args) => {
|
|
320
477
|
await pluginsList(args);
|
|
321
478
|
}).command("get <plugin-name>", "Get a specific plugin configuration", (yargs) => yargs.usage("$0 neon-auth plugins get <plugin-name> [options]").positional("plugin-name", {
|
|
322
|
-
describe: "Plugin name (e.g. organization, email_provider, email_and_password, oauth_providers, allow_localhost)",
|
|
479
|
+
describe: "Plugin name (e.g. organization, email_provider, email_and_password, oauth_providers, oauth_provider, allow_localhost)",
|
|
323
480
|
type: "string",
|
|
324
481
|
demandOption: true
|
|
325
482
|
}), async (args) => {
|
|
@@ -714,6 +871,287 @@ const organizationUpdate = async (props) => {
|
|
|
714
871
|
}
|
|
715
872
|
printKvBlock("Organization configuration updated", printOrganizationEntries(data));
|
|
716
873
|
};
|
|
874
|
+
const optionalBool = (v) => v === void 0 ? void 0 : String(v);
|
|
875
|
+
const printOAuthServerEntries = (data) => [
|
|
876
|
+
["Enabled:", String(data.enabled)],
|
|
877
|
+
["Login Page:", data.login_page],
|
|
878
|
+
["Consent Page:", data.consent_page],
|
|
879
|
+
["MCP Resource:", data.mcp?.resource],
|
|
880
|
+
["MCP CIMD:", optionalBool(data.mcp?.client_id_metadata_documents)],
|
|
881
|
+
["MCP Dynamic Reg:", optionalBool(data.mcp?.dynamic_registration)],
|
|
882
|
+
["Resources:", (data.resources ?? []).map((r) => r.identifier).join(", ")]
|
|
883
|
+
];
|
|
884
|
+
/** The API rejects an empty PATCH, so fail before any request with the flags that would do something. */
|
|
885
|
+
const requireUpdateFields = (provided, flags) => {
|
|
886
|
+
if (provided.every((value) => value === void 0)) throw new Error(`Nothing to update. Pass at least one of ${flags.join(", ")}.`);
|
|
887
|
+
};
|
|
888
|
+
const oauthServerGet = async (props) => {
|
|
889
|
+
const branchId = await resolveBranch(props);
|
|
890
|
+
const { data } = await props.apiClient.getNeonAuthOAuthProviderPlugin(props.projectId, branchId);
|
|
891
|
+
if (props.output === "json" || props.output === "yaml") {
|
|
892
|
+
writer(props).end(data, { fields: OAUTH_SERVER_FIELDS });
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
printKvBlock("OAuth server configuration", printOAuthServerEntries(data));
|
|
896
|
+
};
|
|
897
|
+
/**
|
|
898
|
+
* The API requires `mcp.resource` whenever `mcp` is sent and keeps stored booleans that are
|
|
899
|
+
* omitted, so only the resource is filled in from the stored config.
|
|
900
|
+
*/
|
|
901
|
+
const resolveMcpUpdate = async (props, getStoredMcp) => {
|
|
902
|
+
const { mcpResource, mcpDynamicRegistration: dynamicRegistration, mcpClientIdMetadataDocuments: clientIdMetadataDocuments } = props;
|
|
903
|
+
if (mcpResource === void 0 && dynamicRegistration === void 0 && clientIdMetadataDocuments === void 0) return;
|
|
904
|
+
const resource = mcpResource ?? (await getStoredMcp())?.resource;
|
|
905
|
+
if (!resource) throw new Error("No MCP resource is configured yet. Pass --mcp-resource <url> together with the other --mcp-* flags.");
|
|
906
|
+
return {
|
|
907
|
+
resource,
|
|
908
|
+
dynamic_registration: dynamicRegistration,
|
|
909
|
+
client_id_metadata_documents: clientIdMetadataDocuments
|
|
910
|
+
};
|
|
911
|
+
};
|
|
912
|
+
/**
|
|
913
|
+
* Order-preserving dedupe after trimming: padded input would otherwise miss stored values
|
|
914
|
+
* and reach the API as a distinct string, and repeats would be sent as duplicates.
|
|
915
|
+
*/
|
|
916
|
+
const unique = (values) => [...new Set(values.map((value) => value.trim()))];
|
|
917
|
+
/** yargs negation turns `--no-<flag>` on an array option into `[false]`, which bypasses empty-array checks. */
|
|
918
|
+
const isNegatedList = (values) => values === false || Array.isArray(values) && values.includes(false);
|
|
919
|
+
const hasBlank = (values) => values?.some((value) => value.trim() === "") ?? false;
|
|
920
|
+
/** Fails before any request when a list flag was passed with no values or a blank one. */
|
|
921
|
+
const requireNonEmptyLists = (lists) => {
|
|
922
|
+
for (const [flag, values] of lists) {
|
|
923
|
+
if (isNegatedList(values)) throw new Error(`--no-${flag.slice(2)} is not supported. ${flag} must list at least one value.`);
|
|
924
|
+
if (values?.length === 0) throw new Error(`${flag} must list at least one value.`);
|
|
925
|
+
if (hasBlank(values)) throw new Error(`${flag} must not contain empty values.`);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
/**
|
|
929
|
+
* yargs negation turns `--no-<flag>` on a string option into `false`, and `--flag ""` yields an
|
|
930
|
+
* empty string; both would otherwise crash on `.trim()` or be sent to the API.
|
|
931
|
+
*/
|
|
932
|
+
const requireNonBlankString = (flag, value, hint) => {
|
|
933
|
+
if (value === false) throw new Error(`--no-${flag.slice(2)} is not supported. ${hint}`);
|
|
934
|
+
if (typeof value === "string" && value.trim() === "") throw new Error(`${flag} must not be empty.`);
|
|
935
|
+
};
|
|
936
|
+
const requireNonBlankUrls = (urls) => {
|
|
937
|
+
if (hasBlank(urls)) throw new Error("URLs must not be empty.");
|
|
938
|
+
};
|
|
939
|
+
/** The MCP resource is linked to MCP clients on its own, so it cannot also be a protected resource. */
|
|
940
|
+
const rejectMcpResourceCollision = (urls, mcpResource) => {
|
|
941
|
+
if (mcpResource && urls.includes(mcpResource)) throw new Error(`${mcpResource} is the MCP resource and cannot also be a protected resource.`);
|
|
942
|
+
};
|
|
943
|
+
/** Checked before any request so a malformed invocation never reaches the API. */
|
|
944
|
+
const validateOAuthServerUpdate = (props) => {
|
|
945
|
+
requireNonBlankString("--login-page", props.loginPage, "Pass --login-page <url>.");
|
|
946
|
+
requireNonBlankString("--consent-page", props.consentPage, "Pass --consent-page <url>.");
|
|
947
|
+
if (props.mcp === true) throw new Error("--mcp cannot be enabled. Configure MCP with --mcp-resource <url>, or remove it with --no-mcp.");
|
|
948
|
+
if (props.mcp === false && (props.mcpResource !== void 0 || props.mcpClientIdMetadataDocuments !== void 0 || props.mcpDynamicRegistration !== void 0)) throw new Error("--no-mcp cannot be combined with --mcp-resource, --mcp-client-id-metadata-documents or --mcp-dynamic-registration.");
|
|
949
|
+
if (props.mcpResource === false) throw new Error("--no-mcp-resource is not supported. To remove the MCP configuration, use --no-mcp.");
|
|
950
|
+
if (props.mcpResource?.trim() === "") throw new Error("--mcp-resource must not be empty. To remove the MCP configuration, use --no-mcp.");
|
|
951
|
+
if (isNegatedList(props.resources)) throw new Error("--no-resources is not supported. To remove resources, use `neon-auth config oauth-server resource remove <url...>`.");
|
|
952
|
+
if (props.resources?.length === 0) throw new Error("--resources must list at least one URL. To remove resources, use `neon-auth config oauth-server resource remove <url...>`.");
|
|
953
|
+
if (hasBlank(props.resources)) throw new Error("--resources must not contain empty values.");
|
|
954
|
+
};
|
|
955
|
+
const oauthServerUpdate = async (props) => {
|
|
956
|
+
requireUpdateFields([
|
|
957
|
+
props.enabled,
|
|
958
|
+
props.loginPage,
|
|
959
|
+
props.consentPage,
|
|
960
|
+
props.resources,
|
|
961
|
+
props.mcp,
|
|
962
|
+
props.mcpResource,
|
|
963
|
+
props.mcpClientIdMetadataDocuments,
|
|
964
|
+
props.mcpDynamicRegistration
|
|
965
|
+
], [
|
|
966
|
+
"--enabled",
|
|
967
|
+
"--login-page",
|
|
968
|
+
"--consent-page",
|
|
969
|
+
"--resources",
|
|
970
|
+
"--no-mcp",
|
|
971
|
+
"--mcp-resource",
|
|
972
|
+
"--mcp-client-id-metadata-documents"
|
|
973
|
+
]);
|
|
974
|
+
validateOAuthServerUpdate(props);
|
|
975
|
+
const loginPage = props.loginPage?.trim();
|
|
976
|
+
const consentPage = props.consentPage?.trim();
|
|
977
|
+
const mcpResource = props.mcpResource?.trim();
|
|
978
|
+
const branchId = await resolveBranch(props);
|
|
979
|
+
let storedMcp;
|
|
980
|
+
const getStoredMcp = () => storedMcp ??= props.apiClient.getNeonAuthOAuthProviderPlugin(props.projectId, branchId).then(({ data }) => data.mcp);
|
|
981
|
+
const mcp = props.mcp === false ? { resource: "" } : await resolveMcpUpdate({
|
|
982
|
+
...props,
|
|
983
|
+
mcpResource
|
|
984
|
+
}, getStoredMcp);
|
|
985
|
+
const resources = props.resources && unique(props.resources);
|
|
986
|
+
if (resources && props.mcp !== false) rejectMcpResourceCollision(resources, mcp?.resource ?? (await getStoredMcp())?.resource);
|
|
987
|
+
if (props.mcpDynamicRegistration !== void 0) log.warning("--mcp-dynamic-registration is deprecated. Use --mcp-client-id-metadata-documents instead.");
|
|
988
|
+
const { data } = await props.apiClient.updateNeonAuthOAuthProviderPlugin(props.projectId, branchId, {
|
|
989
|
+
enabled: props.enabled,
|
|
990
|
+
login_page: loginPage,
|
|
991
|
+
consent_page: consentPage,
|
|
992
|
+
mcp,
|
|
993
|
+
resources: resources?.map((identifier) => ({ identifier }))
|
|
994
|
+
});
|
|
995
|
+
if (props.output === "json" || props.output === "yaml") {
|
|
996
|
+
writer(props).end(data, { fields: OAUTH_SERVER_FIELDS });
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
printKvBlock("OAuth server configuration updated", printOAuthServerEntries(data));
|
|
1000
|
+
};
|
|
1001
|
+
const getStoredOAuthServer = async (props) => {
|
|
1002
|
+
const branchId = await resolveBranch(props);
|
|
1003
|
+
const { data } = await props.apiClient.getNeonAuthOAuthProviderPlugin(props.projectId, branchId);
|
|
1004
|
+
return {
|
|
1005
|
+
branchId,
|
|
1006
|
+
mcpResource: data.mcp?.resource,
|
|
1007
|
+
stored: (data.resources ?? []).map((r) => r.identifier)
|
|
1008
|
+
};
|
|
1009
|
+
};
|
|
1010
|
+
const reportOAuthResources = (props, resources) => {
|
|
1011
|
+
if (resources.length === 0 && props.output === "table") {
|
|
1012
|
+
printMessage("No protected resources are configured");
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
writer(props).end(resources, { fields: ["identifier"] });
|
|
1016
|
+
};
|
|
1017
|
+
/** The API replaces the whole list, so every change is a full-list PATCH. */
|
|
1018
|
+
const replaceOAuthResources = async (props, branchId, identifiers) => {
|
|
1019
|
+
const { data } = await props.apiClient.updateNeonAuthOAuthProviderPlugin(props.projectId, branchId, { resources: identifiers.map((identifier) => ({ identifier })) });
|
|
1020
|
+
reportOAuthResources(props, data.resources ?? []);
|
|
1021
|
+
};
|
|
1022
|
+
const oauthResourceList = async (props) => {
|
|
1023
|
+
const { stored } = await getStoredOAuthServer(props);
|
|
1024
|
+
reportOAuthResources(props, stored.map((identifier) => ({ identifier })));
|
|
1025
|
+
};
|
|
1026
|
+
const oauthResourceAdd = async (props) => {
|
|
1027
|
+
requireNonBlankUrls(props.url);
|
|
1028
|
+
const urls = unique(props.url);
|
|
1029
|
+
const { branchId, mcpResource, stored } = await getStoredOAuthServer(props);
|
|
1030
|
+
rejectMcpResourceCollision(urls, mcpResource);
|
|
1031
|
+
const existing = urls.filter((url) => stored.includes(url));
|
|
1032
|
+
if (existing.length > 0) log.warning(`Already configured, skipped: ${existing.join(", ")}`);
|
|
1033
|
+
const added = urls.filter((url) => !stored.includes(url));
|
|
1034
|
+
if (added.length === 0) {
|
|
1035
|
+
reportOAuthResources(props, stored.map((identifier) => ({ identifier })));
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
await replaceOAuthResources(props, branchId, [...stored, ...added]);
|
|
1039
|
+
};
|
|
1040
|
+
const oauthResourceRemove = async (props) => {
|
|
1041
|
+
requireNonBlankUrls(props.url);
|
|
1042
|
+
const requested = unique(props.url);
|
|
1043
|
+
const { branchId, stored } = await getStoredOAuthServer(props);
|
|
1044
|
+
const unknown = requested.filter((url) => !stored.includes(url));
|
|
1045
|
+
if (unknown.length > 0) log.warning(`Not configured, skipped: ${unknown.join(", ")}`);
|
|
1046
|
+
const urls = requested.filter((url) => stored.includes(url));
|
|
1047
|
+
if (urls.length === 0) {
|
|
1048
|
+
reportOAuthResources(props, stored.map((identifier) => ({ identifier })));
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
await replaceOAuthResources(props, branchId, stored.filter((url) => !urls.includes(url)));
|
|
1052
|
+
let linked;
|
|
1053
|
+
try {
|
|
1054
|
+
const { data } = await props.apiClient.listNeonAuthOAuthClients(props.projectId, branchId);
|
|
1055
|
+
linked = data.clients.filter((client) => client.resources.some((resource) => urls.includes(resource)));
|
|
1056
|
+
} catch (err) {
|
|
1057
|
+
log.debug("Could not look up clients linked to the removed resource: %s", err);
|
|
1058
|
+
log.warning("Removed, but could not check for clients still linked to it.");
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
if (linked.length > 0) log.warning(`Clients still linked to a removed resource: ${linked.map((client) => `"${client.name}" (${client.client_id})`).join(", ")}. Their token requests for that resource may fail until it is added again.`);
|
|
1062
|
+
};
|
|
1063
|
+
const printOAuthClientEntries = (data) => [
|
|
1064
|
+
["Client ID:", data.client_id],
|
|
1065
|
+
["Name:", data.name],
|
|
1066
|
+
["Type:", data.type],
|
|
1067
|
+
["Redirect URIs:", data.redirect_uris.join(", ")],
|
|
1068
|
+
["Resources:", data.resources.join(", ")],
|
|
1069
|
+
["Skip Consent:", String(data.skip_consent)],
|
|
1070
|
+
["Disabled:", String(data.disabled)],
|
|
1071
|
+
["Created At:", data.created_at]
|
|
1072
|
+
];
|
|
1073
|
+
const oauthClientList = async (props) => {
|
|
1074
|
+
const branchId = await resolveBranch(props);
|
|
1075
|
+
const { data } = await props.apiClient.listNeonAuthOAuthClients(props.projectId, branchId);
|
|
1076
|
+
if (data.clients.length === 0 && props.output === "table") {
|
|
1077
|
+
printMessage("No OAuth clients are configured for this branch.");
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
writer(props).end(data.clients, { fields: OAUTH_CLIENT_FIELDS });
|
|
1081
|
+
};
|
|
1082
|
+
/**
|
|
1083
|
+
* The secret is shown only once, so human output keeps it on its own last line of stdout
|
|
1084
|
+
* and the notice goes to stderr. Structured output keeps it in the object for scripts.
|
|
1085
|
+
*/
|
|
1086
|
+
const reportOAuthClientSecret = (props, data, fields, entries, title) => {
|
|
1087
|
+
if (props.output === "table") {
|
|
1088
|
+
printKvBlock(title, entries);
|
|
1089
|
+
if (data.client_secret) writeStyled(`${data.client_secret}\n`);
|
|
1090
|
+
} else writer(props).end(data, { fields });
|
|
1091
|
+
if (data.client_secret) log.warning("Store this secret now: it is not shown again.");
|
|
1092
|
+
};
|
|
1093
|
+
const oauthClientCreate = async (props) => {
|
|
1094
|
+
requireNonBlankString("--name", props.name, "Pass --name <name>.");
|
|
1095
|
+
requireNonEmptyLists([["--redirect-uris", props.redirectUris], ["--resources", props.resources]]);
|
|
1096
|
+
const branchId = await resolveBranch(props);
|
|
1097
|
+
const { data } = await props.apiClient.createNeonAuthOAuthClient(props.projectId, branchId, {
|
|
1098
|
+
name: props.name.trim(),
|
|
1099
|
+
type: props.type,
|
|
1100
|
+
redirect_uris: unique(props.redirectUris),
|
|
1101
|
+
resources: unique(props.resources),
|
|
1102
|
+
skip_consent: props.skipConsent
|
|
1103
|
+
});
|
|
1104
|
+
reportOAuthClientSecret(props, data, [...OAUTH_CLIENT_FIELDS, "client_secret"], printOAuthClientEntries(data), "OAuth client");
|
|
1105
|
+
};
|
|
1106
|
+
const oauthClientGet = async (props) => {
|
|
1107
|
+
const branchId = await resolveBranch(props);
|
|
1108
|
+
const { data } = await props.apiClient.getNeonAuthOAuthClient(props.projectId, branchId, props.clientId);
|
|
1109
|
+
if (props.output === "json" || props.output === "yaml") {
|
|
1110
|
+
writer(props).end(data, { fields: OAUTH_CLIENT_FIELDS });
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
printKvBlock("OAuth client", printOAuthClientEntries(data));
|
|
1114
|
+
};
|
|
1115
|
+
const oauthClientUpdate = async (props) => {
|
|
1116
|
+
requireNonBlankString("--name", props.name, "Pass --name <name>.");
|
|
1117
|
+
requireNonEmptyLists([["--redirect-uris", props.redirectUris], ["--resources", props.resources]]);
|
|
1118
|
+
requireUpdateFields([
|
|
1119
|
+
props.name,
|
|
1120
|
+
props.redirectUris,
|
|
1121
|
+
props.resources,
|
|
1122
|
+
props.skipConsent,
|
|
1123
|
+
props.disabled
|
|
1124
|
+
], [
|
|
1125
|
+
"--name",
|
|
1126
|
+
"--redirect-uris",
|
|
1127
|
+
"--resources",
|
|
1128
|
+
"--skip-consent",
|
|
1129
|
+
"--disabled"
|
|
1130
|
+
]);
|
|
1131
|
+
const branchId = await resolveBranch(props);
|
|
1132
|
+
const { data } = await props.apiClient.updateNeonAuthOAuthClient(props.projectId, branchId, props.clientId, {
|
|
1133
|
+
name: props.name?.trim(),
|
|
1134
|
+
redirect_uris: props.redirectUris && unique(props.redirectUris),
|
|
1135
|
+
resources: props.resources && unique(props.resources),
|
|
1136
|
+
skip_consent: props.skipConsent,
|
|
1137
|
+
disabled: props.disabled
|
|
1138
|
+
});
|
|
1139
|
+
if (props.output === "json" || props.output === "yaml") {
|
|
1140
|
+
writer(props).end(data, { fields: OAUTH_CLIENT_FIELDS });
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
printKvBlock("OAuth client updated", printOAuthClientEntries(data));
|
|
1144
|
+
};
|
|
1145
|
+
const oauthClientDelete = async (props) => {
|
|
1146
|
+
const branchId = await resolveBranch(props);
|
|
1147
|
+
await props.apiClient.deleteNeonAuthOAuthClient(props.projectId, branchId, props.clientId);
|
|
1148
|
+
printMessage(`OAuth client "${props.clientId}" deleted`);
|
|
1149
|
+
};
|
|
1150
|
+
const oauthClientRotateSecret = async (props) => {
|
|
1151
|
+
const branchId = await resolveBranch(props);
|
|
1152
|
+
const { data } = await props.apiClient.rotateNeonAuthOAuthClientSecret(props.projectId, branchId, props.clientId);
|
|
1153
|
+
reportOAuthClientSecret(props, data, OAUTH_CLIENT_SECRET_FIELDS, [["Client ID:", data.client_id]], "OAuth client secret");
|
|
1154
|
+
};
|
|
717
1155
|
const printWebhookEntries = (data) => [
|
|
718
1156
|
["Enabled:", String(data.enabled)],
|
|
719
1157
|
["URL:", data.webhook_url ?? ""],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { fillSingleProject } from "../utils/enrichers.js";
|
|
3
|
-
import { y as status } from "./config-
|
|
3
|
+
import { y as status } from "./config-BH_qRHiG.js";
|
|
4
4
|
//#region src/commands/status.ts
|
|
5
5
|
var status_exports = /* @__PURE__ */ __exportAll({
|
|
6
6
|
builder: () => builder,
|
package/dist/api.js
CHANGED
|
@@ -895,6 +895,69 @@ const getApiClient = ({ apiKey, apiHost, requestTimeoutMs = REQUEST_TIMEOUT_MS }
|
|
|
895
895
|
},
|
|
896
896
|
body: data
|
|
897
897
|
})),
|
|
898
|
+
getNeonAuthOAuthProviderPlugin: (projectId, branchId) => call(() => raw.getNeonAuthOAuthProviderPlugin({
|
|
899
|
+
client,
|
|
900
|
+
path: {
|
|
901
|
+
project_id: projectId,
|
|
902
|
+
branch_id: branchId
|
|
903
|
+
}
|
|
904
|
+
})),
|
|
905
|
+
updateNeonAuthOAuthProviderPlugin: (projectId, branchId, data) => call(() => raw.updateNeonAuthOAuthProviderPlugin({
|
|
906
|
+
client,
|
|
907
|
+
path: {
|
|
908
|
+
project_id: projectId,
|
|
909
|
+
branch_id: branchId
|
|
910
|
+
},
|
|
911
|
+
body: data
|
|
912
|
+
})),
|
|
913
|
+
listNeonAuthOAuthClients: (projectId, branchId) => call(() => raw.listNeonAuthOAuthClients({
|
|
914
|
+
client,
|
|
915
|
+
path: {
|
|
916
|
+
project_id: projectId,
|
|
917
|
+
branch_id: branchId
|
|
918
|
+
}
|
|
919
|
+
})),
|
|
920
|
+
createNeonAuthOAuthClient: (projectId, branchId, data) => call(() => raw.createNeonAuthOAuthClient({
|
|
921
|
+
client,
|
|
922
|
+
path: {
|
|
923
|
+
project_id: projectId,
|
|
924
|
+
branch_id: branchId
|
|
925
|
+
},
|
|
926
|
+
body: data
|
|
927
|
+
})),
|
|
928
|
+
getNeonAuthOAuthClient: (projectId, branchId, clientId) => call(() => raw.getNeonAuthOAuthClient({
|
|
929
|
+
client,
|
|
930
|
+
path: {
|
|
931
|
+
project_id: projectId,
|
|
932
|
+
branch_id: branchId,
|
|
933
|
+
client_id: clientId
|
|
934
|
+
}
|
|
935
|
+
})),
|
|
936
|
+
updateNeonAuthOAuthClient: (projectId, branchId, clientId, data) => call(() => raw.updateNeonAuthOAuthClient({
|
|
937
|
+
client,
|
|
938
|
+
path: {
|
|
939
|
+
project_id: projectId,
|
|
940
|
+
branch_id: branchId,
|
|
941
|
+
client_id: clientId
|
|
942
|
+
},
|
|
943
|
+
body: data
|
|
944
|
+
})),
|
|
945
|
+
deleteNeonAuthOAuthClient: (projectId, branchId, clientId) => call(() => raw.deleteNeonAuthOAuthClient({
|
|
946
|
+
client,
|
|
947
|
+
path: {
|
|
948
|
+
project_id: projectId,
|
|
949
|
+
branch_id: branchId,
|
|
950
|
+
client_id: clientId
|
|
951
|
+
}
|
|
952
|
+
})),
|
|
953
|
+
rotateNeonAuthOAuthClientSecret: (projectId, branchId, clientId) => call(() => raw.rotateNeonAuthOAuthClientSecret({
|
|
954
|
+
client,
|
|
955
|
+
path: {
|
|
956
|
+
project_id: projectId,
|
|
957
|
+
branch_id: branchId,
|
|
958
|
+
client_id: clientId
|
|
959
|
+
}
|
|
960
|
+
})),
|
|
898
961
|
getNeonAuthWebhookConfig: (projectId, branchId) => call(() => raw.getNeonAuthWebhookConfig({
|
|
899
962
|
client,
|
|
900
963
|
path: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, r as command, i as describe, a as formatCheckoutPolicyFailure, o as handler } from "../_chunks/checkout-
|
|
1
|
+
export { t as builder, r as command, i as describe, a as formatCheckoutPolicyFailure, o as handler } from "../_chunks/checkout-CXIOydqZ.js";
|
package/dist/commands/claim.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as CLAIM_CREATE_FIELDS, n as CLAIM_LIST_FIELDS, r as aliases, i as builder, a as claimCreateFields, s as claimableCapabilities, c as command, l as create, u as describe, d as handler } from "../_chunks/claim-
|
|
1
|
+
export { t as CLAIM_CREATE_FIELDS, n as CLAIM_LIST_FIELDS, r as aliases, i as builder, a as claimCreateFields, s as claimableCapabilities, c as command, l as create, u as describe, d as handler } from "../_chunks/claim-DqAvAvDm.js";
|
package/dist/commands/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as ConfigInstallFailed, n as addCmd, r as applyCmd, i as applyFlags, a as applyPolicyOnCreate, o as builder, s as command, l as createBranchFromPolicyOnCheckout, u as describe, d as ensureConfigPackages, f as envFlag, p as envPullFlag, m as handler, h as initCmd, g as installCommandFrom, _ as missingDependencies, v as planCmd, y as status } from "../_chunks/config-
|
|
1
|
+
export { t as ConfigInstallFailed, n as addCmd, r as applyCmd, i as applyFlags, a as applyPolicyOnCreate, o as builder, s as command, l as createBranchFromPolicyOnCheckout, u as describe, d as ensureConfigPackages, f as envFlag, p as envPullFlag, m as handler, h as initCmd, g as installCommandFrom, _ as missingDependencies, v as planCmd, y as status } from "../_chunks/config-BH_qRHiG.js";
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-
|
|
1
|
+
export { t as builder, n as command, i as describe, a as handler } from "../_chunks/deploy-D7B0Xfjg.js";
|
package/dist/commands/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as captureShellEnv, r as command, i as describe, a as devBundleDir, o as devEnvContext, c as diffUnits, l as formatEnvFiles, u as formatEnvSummary, d as handler, f as loadDevEnvFiles, p as localFunctionUrlEnv, m as planFunctionsToUnits, h as reportDevCredential, g as sourceFunctionUrlOverlay } from "../_chunks/dev-
|
|
1
|
+
export { t as builder, n as captureShellEnv, r as command, i as describe, a as devBundleDir, o as devEnvContext, c as diffUnits, l as formatEnvFiles, u as formatEnvSummary, d as handler, f as loadDevEnvFiles, p as localFunctionUrlEnv, m as planFunctionsToUnits, h as reportDevCredential, g as sourceFunctionUrlOverlay } from "../_chunks/dev-CSvxAecE.js";
|
package/dist/commands/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as ENV_PULL_SKIPPED_HINT, n as autoPullEnvAfterPin, r as builder, i as command, a as describe, s as handler, c as pull } from "../_chunks/env-
|
|
1
|
+
export { t as ENV_PULL_SKIPPED_HINT, n as autoPullEnvAfterPin, r as builder, i as command, a as describe, s as handler, c as pull } from "../_chunks/env-5HS5qQGd.js";
|
|
@@ -8,7 +8,7 @@ import { writer } from "../writer.js";
|
|
|
8
8
|
import { formatInitDone, printInitDone } from "../init/chrome.js";
|
|
9
9
|
import { FUNCTION_SLUG_PATTERN, deriveFunctionSlug } from "../utils/function_slug.js";
|
|
10
10
|
import { displayPath } from "./env_output.js";
|
|
11
|
-
import { _ as missingDependencies, d as ensureConfigPackages, g as installCommandFrom } from "../_chunks/config-
|
|
11
|
+
import { _ as missingDependencies, d as ensureConfigPackages, g as installCommandFrom } from "../_chunks/config-BH_qRHiG.js";
|
|
12
12
|
import { recommendedOperations } from "../functions/registry.js";
|
|
13
13
|
import { collidingFiles, operationsFromFlags, planConfigRegistration, planEnvExample, planScaffold, writeScaffold } from "../functions/scaffold.js";
|
|
14
14
|
import { describeRegistrySource, openRegistry } from "../functions/source.js";
|
package/dist/commands/git.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as aliases, n as builder, r as cleanup, i as command, a as describe, s as handler, c as install, l as partitionBranchesToPrune, u as status, d as sync, f as uninstall } from "../_chunks/git-
|
|
1
|
+
export { t as aliases, n as builder, r as cleanup, i as command, a as describe, s as handler, c as install, l as partitionBranchesToPrune, u as status, d as sync, f as uninstall } from "../_chunks/git-H32TNt6M.js";
|
package/dist/commands/index.js
CHANGED
|
@@ -2,34 +2,34 @@ import { r as auth_exports } from "../_chunks/auth-CIUtXByB.js";
|
|
|
2
2
|
import { t as api_exports } from "../_chunks/api-GbEaBZJ5.js";
|
|
3
3
|
import { n as api_keys_exports } from "../_chunks/api_keys-CNnnugbQ.js";
|
|
4
4
|
import { n as ask_exports } from "../_chunks/ask-DVwy0eUL.js";
|
|
5
|
-
import { o as env_exports } from "../_chunks/env-
|
|
6
|
-
import { c as config_exports } from "../_chunks/config-
|
|
5
|
+
import { o as env_exports } from "../_chunks/env-5HS5qQGd.js";
|
|
6
|
+
import { c as config_exports } from "../_chunks/config-BH_qRHiG.js";
|
|
7
7
|
import { u as projects_exports } from "../_chunks/projects-BwI2Uo0z.js";
|
|
8
|
-
import { a as link_exports } from "../_chunks/link-
|
|
8
|
+
import { a as link_exports } from "../_chunks/link-BgtkOBws.js";
|
|
9
9
|
import { o as mcp_exports } from "../_chunks/mcp-Bo-7TKc7.js";
|
|
10
10
|
import { c as plugins_exports } from "../_chunks/plugins-DqD7BDO1.js";
|
|
11
11
|
import { l as skills_exports } from "../_chunks/skills-BP6pIm7O.js";
|
|
12
12
|
import { t as bootstrap_exports } from "../_chunks/bootstrap-wPZWa1sT.js";
|
|
13
13
|
import { r as branches_exports } from "../_chunks/branches-BNa1xX1L.js";
|
|
14
14
|
import { n as bucket_exports } from "../_chunks/bucket-BCdryTkD.js";
|
|
15
|
-
import { n as checkout_exports } from "../_chunks/checkout-
|
|
16
|
-
import { o as claim_exports } from "../_chunks/claim-
|
|
15
|
+
import { n as checkout_exports } from "../_chunks/checkout-CXIOydqZ.js";
|
|
16
|
+
import { o as claim_exports } from "../_chunks/claim-DqAvAvDm.js";
|
|
17
17
|
import { a as connection_string_exports } from "../_chunks/connection_string-DB4awPzZ.js";
|
|
18
18
|
import { a as credentials_exports } from "../_chunks/credentials-BSjE9fRR.js";
|
|
19
19
|
import { r as data_api_exports } from "../_chunks/data_api-Djxj5ZQD.js";
|
|
20
20
|
import { o as databases_exports } from "../_chunks/databases-Dok4wru7.js";
|
|
21
|
-
import { r as deploy_exports } from "../_chunks/deploy-
|
|
22
|
-
import { s as dev_exports } from "../_chunks/dev-
|
|
21
|
+
import { r as deploy_exports } from "../_chunks/deploy-D7B0Xfjg.js";
|
|
22
|
+
import { s as dev_exports } from "../_chunks/dev-CSvxAecE.js";
|
|
23
23
|
import { i as diff_exports } from "../_chunks/diff-DhxxbdQE.js";
|
|
24
24
|
import { c as docs_exports } from "../_chunks/docs-CrVybkTP.js";
|
|
25
25
|
import { o as feedback_exports } from "../_chunks/feedback-CMayyTa8.js";
|
|
26
26
|
import { o as functions_exports } from "../_chunks/functions-Q0zuvtnk.js";
|
|
27
|
-
import { o as git_exports } from "../_chunks/git-
|
|
27
|
+
import { o as git_exports } from "../_chunks/git-H32TNt6M.js";
|
|
28
28
|
import { a as init_exports } from "../_chunks/init-BkA6RilG.js";
|
|
29
29
|
import { o as inspect_exports } from "../_chunks/inspect-g0wekylj.js";
|
|
30
30
|
import { a as ip_allow_exports } from "../_chunks/ip_allow-5lLFvIuE.js";
|
|
31
31
|
import { l as logs_exports } from "../_chunks/logs-DWkpjzIH.js";
|
|
32
|
-
import { a as neon_auth_exports } from "../_chunks/neon_auth-
|
|
32
|
+
import { a as neon_auth_exports } from "../_chunks/neon_auth-DpF83S24.js";
|
|
33
33
|
import { a as open_exports } from "../_chunks/open-CX3BT3Tp.js";
|
|
34
34
|
import { s as operations_exports } from "../_chunks/operations-D4I-AxVs.js";
|
|
35
35
|
import { o as orgs_exports } from "../_chunks/orgs-xGfANwHQ.js";
|
|
@@ -39,7 +39,7 @@ import { s as realtime_exports } from "../_chunks/realtime-BRqIyGR-.js";
|
|
|
39
39
|
import { l as roles_exports } from "../_chunks/roles-B4w3YT_7.js";
|
|
40
40
|
import { a as set_context_exports } from "../_chunks/set_context-DbrwoImy.js";
|
|
41
41
|
import { s as snapshots_exports } from "../_chunks/snapshots-RJBzW8GM.js";
|
|
42
|
-
import { a as status_exports } from "../_chunks/status-
|
|
42
|
+
import { a as status_exports } from "../_chunks/status-DV8Z2kw3.js";
|
|
43
43
|
import { d as triggers_exports } from "../_chunks/triggers-BrRo1z4b.js";
|
|
44
44
|
import { s as user_exports } from "../_chunks/user-dlOGXbX9.js";
|
|
45
45
|
import { i as vpc_endpoints_exports } from "../_chunks/vpc_endpoints-CNb0YfMo.js";
|
package/dist/commands/link.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, r as describe, i as handler, o as quoteFlagValue, s as runLink, c as shouldOfferConfigInit } from "../_chunks/link-
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler, o as quoteFlagValue, s as runLink, c as shouldOfferConfigInit } from "../_chunks/link-BgtkOBws.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/neon_auth-
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/neon_auth-DpF83S24.js";
|
package/dist/commands/status.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/status-DV8Z2kw3.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writer } from "../writer.js";
|
|
2
|
-
import { o as resolveNeonEnvVars } from "../_chunks/env-BNm69Qh8.js";
|
|
3
2
|
import { branchIdFromProps } from "../utils/enrichers.js";
|
|
3
|
+
import { o as resolveNeonEnvVars } from "../_chunks/env-BNm69Qh8.js";
|
|
4
4
|
import YAML from "yaml";
|
|
5
5
|
//#region src/commands/subscribe.ts
|
|
6
6
|
const builder = (argv) => argv.usage("$0 realtime subscribe \"<query>\" [options]").positional("query", {
|
package/dist/init/auth.js
CHANGED
|
@@ -4,7 +4,7 @@ import "../config.js";
|
|
|
4
4
|
import "../auth.js";
|
|
5
5
|
import { c as ensureAuth } from "../_chunks/auth-CIUtXByB.js";
|
|
6
6
|
import { recoverFrom401 } from "../auth_recovery.js";
|
|
7
|
-
import { c as pull } from "../_chunks/env-
|
|
7
|
+
import { c as pull } from "../_chunks/env-5HS5qQGd.js";
|
|
8
8
|
import { c as setupNeonMcp } from "../_chunks/mcp-Bo-7TKc7.js";
|
|
9
9
|
//#region src/init/auth.ts
|
|
10
10
|
const isUnauthorized = (error) => isNeonApiError(error) && error.status === 401;
|
package/dist/init/link.js
CHANGED
|
@@ -4,7 +4,7 @@ import "../config.js";
|
|
|
4
4
|
import "../auth.js";
|
|
5
5
|
import { c as ensureAuth } from "../_chunks/auth-CIUtXByB.js";
|
|
6
6
|
import { recoverFrom401 } from "../auth_recovery.js";
|
|
7
|
-
import { s as runLink } from "../_chunks/link-
|
|
7
|
+
import { s as runLink } from "../_chunks/link-BgtkOBws.js";
|
|
8
8
|
//#region src/init/link.ts
|
|
9
9
|
const isUnauthorized = (error) => isNeonApiError(error) && error.status === 401;
|
|
10
10
|
const authenticationFailed = () => /* @__PURE__ */ new Error("Authentication failed.");
|
package/dist/init/run.js
CHANGED
|
@@ -17,15 +17,15 @@ import { FALLBACK_SKILLS_AGENTS, assertNamedAgentTooling, funnelAgentSetup, plan
|
|
|
17
17
|
import { inferPackageManager, resolvePackageManager } from "../utils/package_manager.js";
|
|
18
18
|
import { CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, MCP_API_KEY_NEEDS_AUTH, MCP_SCOPED_NEEDS_PROJECT, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, PROGRESS, PROJECT_PINNED_OFFLINE, claimableNext, claimableThenServicesNext, configInitNext, envPullFailedNext, existingConfigNext, installFailedNext, mcpAfterLinkNext, mcpConfigLocationSkipped, mcpConfigLocationUnavailable, mcpKeyFailedNext, namedAgentsUnavailable, newConfigNext, offlinePinNext, skippedLinkNext, unattendedUnauthedNext } from "./copy.js";
|
|
19
19
|
import { agentsRowValue, configRowValue, formatInitDone, headingForKind, printInitBanner, printInitDone, printInitProgress, projectRowValue, shouldPrintInitBanner } from "./chrome.js";
|
|
20
|
-
import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-
|
|
21
|
-
import { o as quoteFlagValue, s as runLink } from "../_chunks/link-
|
|
20
|
+
import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-BH_qRHiG.js";
|
|
21
|
+
import { o as quoteFlagValue, s as runLink } from "../_chunks/link-BgtkOBws.js";
|
|
22
22
|
import { runAuthenticatedLink } from "./link.js";
|
|
23
23
|
import { CannotMintApiKeyError } from "../mcp/mint.js";
|
|
24
24
|
import { pullInitEnv } from "./auth.js";
|
|
25
25
|
import { InitCancelled, raceSigint, restoreCursor } from "./cancelled.js";
|
|
26
26
|
import { pickAgentSetupInteractively, pickInitAgentsInteractively, pickInitConfigInteractively, pickInitMcpAuthInteractively, pickInitMcpConfigLocationInteractively, pickInitModeInteractively, pickInitPackageManagerInteractively, pickInitProjectSetupInteractively, pickInitServicesInteractively, pickInitSkillsInteractively } from "./wizard.js";
|
|
27
27
|
import { runToolingSteps } from "./tooling.js";
|
|
28
|
-
import { l as create } from "../_chunks/claim-
|
|
28
|
+
import { l as create } from "../_chunks/claim-DqAvAvDm.js";
|
|
29
29
|
import { INIT_CONFIG_SERVICES_CONFLICT, configPlanFromResolution, initEnvPullAfterConfig, resolveInitConfigChoice } from "./choices.js";
|
|
30
30
|
import { detectInitEnvironment } from "./detect.js";
|
|
31
31
|
import { createInitFunnel, emitInitStart, finishInitFunnel, initStartProperties } from "./funnel.js";
|
package/dist/skills/freshness.js
CHANGED
|
@@ -83,17 +83,23 @@ const folderKey = ({ source, folder }) => `${source}:${folder}`;
|
|
|
83
83
|
/** `undefined` when the remote side has not been fetched yet. */
|
|
84
84
|
const skillStatus = (skill, remote) => {
|
|
85
85
|
if (remote?.missing === true) return "not found upstream";
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if (skill.hashKind === "tree") {
|
|
87
|
+
if (remote?.tree === void 0) return void 0;
|
|
88
|
+
return remote.tree === skill.hash ? "up to date" : "outdated";
|
|
89
|
+
}
|
|
90
|
+
if (remote?.content === void 0) return void 0;
|
|
91
|
+
if (skill.hash === remote.content) return "up to date";
|
|
92
|
+
if (remote.contentCrlf === void 0) return void 0;
|
|
93
|
+
return skill.hash === remote.contentCrlf ? "up to date" : "outdated";
|
|
89
94
|
};
|
|
90
95
|
const parseRemoteFolder = (value) => {
|
|
91
96
|
if (!isRecord(value)) return void 0;
|
|
92
|
-
const { tree, content, missing, pending } = value;
|
|
93
|
-
if (tree !== void 0 && typeof tree !== "string" || content !== void 0 && typeof content !== "string" || missing !== void 0 && missing !== true || pending !== void 0 && pending !== true) return;
|
|
97
|
+
const { tree, content, contentCrlf, missing, pending } = value;
|
|
98
|
+
if (tree !== void 0 && typeof tree !== "string" || content !== void 0 && typeof content !== "string" || contentCrlf !== void 0 && typeof contentCrlf !== "string" || missing !== void 0 && missing !== true || pending !== void 0 && pending !== true) return;
|
|
94
99
|
return {
|
|
95
100
|
...tree === void 0 ? {} : { tree },
|
|
96
101
|
...content === void 0 ? {} : { content },
|
|
102
|
+
...contentCrlf === void 0 ? {} : { contentCrlf },
|
|
97
103
|
...missing === void 0 ? {} : { missing },
|
|
98
104
|
...pending === void 0 ? {} : { pending }
|
|
99
105
|
};
|
|
@@ -137,6 +143,41 @@ const skillContentHash = (files) => {
|
|
|
137
143
|
}
|
|
138
144
|
return hash.digest("hex");
|
|
139
145
|
};
|
|
146
|
+
const LF = 10;
|
|
147
|
+
const CR = 13;
|
|
148
|
+
/** Control bytes Git counts as printable text: backspace, tab, form feed, escape. */
|
|
149
|
+
const PRINTABLE_CONTROLS = /* @__PURE__ */ new Set([
|
|
150
|
+
8,
|
|
151
|
+
9,
|
|
152
|
+
12,
|
|
153
|
+
27
|
|
154
|
+
]);
|
|
155
|
+
/**
|
|
156
|
+
* The bytes Git writes for a blob when `core.autocrlf=true`, the Git for Windows default. The
|
|
157
|
+
* skills CLI hashes that checkout, so a Windows install records a hash of these bytes. Mirrors
|
|
158
|
+
* Git's `convert.c`: a blob that has any CR, a NUL, or mostly non-printable bytes is written
|
|
159
|
+
* unchanged, and every LF in any other blob becomes CRLF.
|
|
160
|
+
*/
|
|
161
|
+
const autocrlfCheckout = (bytes) => {
|
|
162
|
+
let lf = 0;
|
|
163
|
+
let printable = 0;
|
|
164
|
+
let nonprintable = 0;
|
|
165
|
+
for (const byte of bytes) {
|
|
166
|
+
if (byte === CR || byte === 0) return bytes;
|
|
167
|
+
if (byte === LF) lf += 1;
|
|
168
|
+
else if (byte === 127 || byte < 32 && !PRINTABLE_CONTROLS.has(byte)) nonprintable += 1;
|
|
169
|
+
else printable += 1;
|
|
170
|
+
}
|
|
171
|
+
if (bytes[bytes.length - 1] === 26) nonprintable -= 1;
|
|
172
|
+
if (lf === 0 || printable >> 7 < nonprintable) return bytes;
|
|
173
|
+
const out = new Uint8Array(bytes.length + lf);
|
|
174
|
+
let at = 0;
|
|
175
|
+
for (const byte of bytes) {
|
|
176
|
+
if (byte === LF) out[at++] = CR;
|
|
177
|
+
out[at++] = byte;
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
};
|
|
140
181
|
const gitBlobSha = (bytes) => createHash("sha1").update(`blob ${bytes.byteLength}\0`).update(bytes).digest("hex");
|
|
141
182
|
const isTreeEntry = (value) => isRecord(value) && typeof value.path === "string" && typeof value.mode === "string" && typeof value.type === "string" && typeof value.sha === "string";
|
|
142
183
|
const githubHeaders = (env) => {
|
|
@@ -168,7 +209,7 @@ const folderFiles = (tree, folder) => tree.filter((entry) => {
|
|
|
168
209
|
const dirs = entry.path.slice(folder.length + 1).split("/").slice(0, -1);
|
|
169
210
|
return !dirs.includes(".git") && !dirs.includes("node_modules");
|
|
170
211
|
});
|
|
171
|
-
const
|
|
212
|
+
const fetchContentHashes = async (source, folder, tree) => {
|
|
172
213
|
const files = await Promise.all(folderFiles(tree, folder).map(async (entry) => {
|
|
173
214
|
const path = entry.path.split("/").map(encodeURIComponent).join("/");
|
|
174
215
|
const response = await fetch(`https://raw.githubusercontent.com/${source}/HEAD/${path}`, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
@@ -180,7 +221,13 @@ const fetchContentHash = async (source, folder, tree) => {
|
|
|
180
221
|
bytes
|
|
181
222
|
};
|
|
182
223
|
}));
|
|
183
|
-
return
|
|
224
|
+
return {
|
|
225
|
+
content: skillContentHash(files),
|
|
226
|
+
contentCrlf: skillContentHash(files.map((file) => ({
|
|
227
|
+
...file,
|
|
228
|
+
bytes: autocrlfCheckout(file.bytes)
|
|
229
|
+
})))
|
|
230
|
+
};
|
|
184
231
|
};
|
|
185
232
|
/**
|
|
186
233
|
* The folders to fetch: the given skills, plus every folder already in the cache so
|
|
@@ -232,11 +279,14 @@ const refreshSkillsCheckCache = async ({ cachePath, skills, env = process.env, n
|
|
|
232
279
|
continue;
|
|
233
280
|
}
|
|
234
281
|
const prior = previous[key];
|
|
235
|
-
let
|
|
236
|
-
|
|
282
|
+
let hashes = prior?.tree === node.sha && prior.content !== void 0 && prior.contentCrlf !== void 0 ? {
|
|
283
|
+
content: prior.content,
|
|
284
|
+
contentCrlf: prior.contentCrlf
|
|
285
|
+
} : void 0;
|
|
286
|
+
if (request.content && hashes === void 0) hashes = await fetchContentHashes(source, request.folder, tree);
|
|
237
287
|
folders[key] = {
|
|
238
288
|
tree: node.sha,
|
|
239
|
-
...
|
|
289
|
+
...hashes
|
|
240
290
|
};
|
|
241
291
|
}
|
|
242
292
|
}
|
|
@@ -394,4 +444,4 @@ const notifyIfSkillsOutdated = ({ configDir, cwd, now = Date.now() }) => {
|
|
|
394
444
|
}, "skills check cache")) spawnSkillsCheckWorker(cachePath, cwd);
|
|
395
445
|
};
|
|
396
446
|
//#endregion
|
|
397
|
-
export { formatSkillsNotice, globalLockPath, lockPath, neonSkillsUpdateCommand, notifyIfSkillsOutdated, parseSkillsCheckCache, parseSkillsLock, planSkillsCheck, projectLockPath, readLockedSkills, readSkillsTelemetry, refreshSkillsCheckCache, scopeLabel, skillContentHash, skillStatus, skillsCheckCachePath, skillsStatusRows, skillsTelemetry };
|
|
447
|
+
export { autocrlfCheckout, formatSkillsNotice, globalLockPath, lockPath, neonSkillsUpdateCommand, notifyIfSkillsOutdated, parseSkillsCheckCache, parseSkillsLock, planSkillsCheck, projectLockPath, readLockedSkills, readSkillsTelemetry, refreshSkillsCheckCache, scopeLabel, skillContentHash, skillStatus, skillsCheckCachePath, skillsStatusRows, skillsTelemetry };
|
package/dist/skills/run.js
CHANGED
|
@@ -37,11 +37,13 @@ const assertSkillsNode = (version = process.version) => {
|
|
|
37
37
|
if (nodeMeetsMinimum(version, "22.20.0")) return;
|
|
38
38
|
throw new Error(`neon skills needs Node.js ${SKILLS_MIN_NODE} or newer to run the skills CLI. This process is Node.js ${version.replace(/^v/, "")}. Upgrade Node.js, then retry.`);
|
|
39
39
|
};
|
|
40
|
+
/** A bare `skills` makes npx run any copy already installed globally or cached, however old. */
|
|
41
|
+
const SKILLS_PACKAGE = "skills@latest";
|
|
40
42
|
const skillsAddArgs = (options) => {
|
|
41
43
|
if (options.skills.length === 0) throw new Error("skills add needs at least one --skill.");
|
|
42
44
|
const args = [
|
|
43
45
|
"-y",
|
|
44
|
-
|
|
46
|
+
SKILLS_PACKAGE,
|
|
45
47
|
"add",
|
|
46
48
|
options.source
|
|
47
49
|
];
|
|
@@ -83,7 +85,7 @@ const skillsUpdateDetail = (output) => {
|
|
|
83
85
|
};
|
|
84
86
|
const skillsUpdateArgs = (options) => [
|
|
85
87
|
"-y",
|
|
86
|
-
|
|
88
|
+
SKILLS_PACKAGE,
|
|
87
89
|
"update",
|
|
88
90
|
options.global ? "-g" : "-p",
|
|
89
91
|
"-y"
|
|
@@ -48,14 +48,15 @@ const test = test$1.extend({
|
|
|
48
48
|
let startedServer;
|
|
49
49
|
await use(async (mockDir, onRequest) => {
|
|
50
50
|
const app = express();
|
|
51
|
+
app.use(express.json());
|
|
51
52
|
if (onRequest) app.use((req, _res, next) => {
|
|
52
53
|
onRequest({
|
|
53
54
|
method: req.method,
|
|
54
|
-
path: req.path
|
|
55
|
+
path: req.path,
|
|
56
|
+
body: req.body
|
|
55
57
|
});
|
|
56
58
|
next();
|
|
57
59
|
});
|
|
58
|
-
app.use(express.json());
|
|
59
60
|
app.use("/", emocks(join(process.cwd(), "mocks", mockDir), { "404": (_req, res) => res.status(404).send({ message: "Not Found" }) }));
|
|
60
61
|
const server = await new Promise((resolve) => {
|
|
61
62
|
const s = app.listen(0, () => {
|
|
@@ -76,7 +77,7 @@ const test = test$1.extend({
|
|
|
76
77
|
},
|
|
77
78
|
testCliCommand: async ({ runMockServer }, use) => {
|
|
78
79
|
await use(async (args, options = {}) => {
|
|
79
|
-
const apiHost = options.unreachableHost ? await reserveClosedPort() : `http://localhost:${(await runMockServer(options.mockDir || "main")).address().port}`;
|
|
80
|
+
const apiHost = options.unreachableHost ? await reserveClosedPort() : `http://localhost:${(await runMockServer(options.mockDir || "main", options.onRequest)).address().port}`;
|
|
80
81
|
let output = "";
|
|
81
82
|
let error = "";
|
|
82
83
|
const cp = fork(join(process.cwd(), "./dist/index.js"), [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neon",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.13.1",
|
|
4
4
|
"description": "CLI tool for Neon, the cloud backend primitives built around Lakebase Postgres",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neon",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"yaml": "^2.9.0",
|
|
73
73
|
"yargs": "17.7.2",
|
|
74
74
|
"yoctocolors": "^2.1.2",
|
|
75
|
-
"@neon/config": "1.9.
|
|
76
|
-
"@neon/config-runtime": "1.10.
|
|
75
|
+
"@neon/config": "1.9.5",
|
|
76
|
+
"@neon/config-runtime": "1.10.4",
|
|
77
77
|
"@neon/realtime": "0.1.2",
|
|
78
|
-
"@neon/sdk": "7.
|
|
78
|
+
"@neon/sdk": "7.6.0"
|
|
79
79
|
},
|
|
80
80
|
"optionalDependencies": {
|
|
81
81
|
"@napi-rs/keyring": "1.3.0",
|
|
@@ -112,10 +112,10 @@
|
|
|
112
112
|
"typescript": "^5.9.0",
|
|
113
113
|
"vitest": "^3.0.9",
|
|
114
114
|
"@neon-internals/cli-core": "0.0.0",
|
|
115
|
-
"@neon-internals/env-core": "0.0.
|
|
116
|
-
"@neon/env": "1.6.
|
|
117
|
-
"@neon/
|
|
118
|
-
"@neon/
|
|
115
|
+
"@neon-internals/env-core": "0.0.36",
|
|
116
|
+
"@neon/env": "1.6.6",
|
|
117
|
+
"@neon/e2e-harness": "0.0.0",
|
|
118
|
+
"@neon/functions": "0.11.0"
|
|
119
119
|
},
|
|
120
120
|
"publishConfig": {
|
|
121
121
|
"access": "public",
|
|
@@ -7,9 +7,9 @@ import { deprecatedServiceMessage, parseServices, servicesFlagValue, servicesOpt
|
|
|
7
7
|
import { mergeEnvFile, readEnvFile, resolveEnvFilePath } from "../env_file.js";
|
|
8
8
|
import { t as NEON_ENV_VAR_KEYS, u as isFunctionBaseUrlKey } from "./env-BpP3Dqpe.js";
|
|
9
9
|
import { ENV_PULL_KEY_HELP, ENV_PULL_SERVICES, envKeysForSelection, envPullFlagValue, ownedEnvServiceKeys, parseEnvPullKeys } from "../env_services.js";
|
|
10
|
-
import { i as dropClaimableUnsupported, o as resolveNeonEnvVars } from "./env-BNm69Qh8.js";
|
|
11
10
|
import { fillSingleProject, resolveBranchRef } from "../utils/enrichers.js";
|
|
12
11
|
import { warnAiGateway } from "../utils/ai_gateway_notice.js";
|
|
12
|
+
import { i as dropClaimableUnsupported, o as resolveNeonEnvVars } from "./env-BNm69Qh8.js";
|
|
13
13
|
import { formatPulledEnv, pulledBranch } from "../commands/env_output.js";
|
|
14
14
|
import { existsSync } from "node:fs";
|
|
15
15
|
import chalk from "chalk";
|