@ainyc/canonry 4.81.0 → 4.82.0
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/assets/agent-workspace/skills/canonry/references/canonry-cli.md +4 -0
- package/assets/assets/{BacklinksPage-DHShKKpo.js → BacklinksPage-CHclt-pq.js} +1 -1
- package/assets/assets/{ChartPrimitives-udHScxjY.js → ChartPrimitives-2Ub4vNWe.js} +1 -1
- package/assets/assets/{ProjectPage-BsS1anh7.js → ProjectPage-UPmHfuxR.js} +1 -1
- package/assets/assets/{RunRow-CXyPHMVQ.js → RunRow-rUL1UeA3.js} +1 -1
- package/assets/assets/{RunsPage-BpQ_NpFt.js → RunsPage-BQpHfUJf.js} +1 -1
- package/assets/assets/{SettingsPage-1ep4ch7n.js → SettingsPage-DjTJlr_1.js} +1 -1
- package/assets/assets/{TrafficPage-C3Hx-sE7.js → TrafficPage-D7rv3BrH.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-B26n2R6G.js → TrafficSourceDetailPage-BysyuH2H.js} +1 -1
- package/assets/assets/{arrow-left-Dc_IPJxw.js → arrow-left-CR_FGlkE.js} +1 -1
- package/assets/assets/{extract-error-message-B3PoKkHW.js → extract-error-message-BKkAbWNp.js} +1 -1
- package/assets/assets/{index-DhdFTQkU.js → index-DzzTt20n.js} +11 -11
- package/assets/assets/{trash-2-BQ69cGl0.js → trash-2-uSttujvh.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-UAQ42NVJ.js → chunk-IEUTAQUF.js} +32 -2
- package/dist/{chunk-6XOZSS3Y.js → chunk-JLAD6CYH.js} +17 -1
- package/dist/{chunk-GMT3YPLT.js → chunk-KPSFRSS7.js} +20 -1
- package/dist/{chunk-VX5C7DK7.js → chunk-NSZ3D3MM.js} +4 -4
- package/dist/cli.js +46 -14
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-CAAQAKPN.js → intelligence-service-2UUJ3YGI.js} +2 -2
- package/dist/mcp.js +23 -4
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-DzzTt20n.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
|
package/assets/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-DzzTt20n.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-ClRVR6aX.js">
|
|
@@ -156,6 +156,7 @@ import {
|
|
|
156
156
|
hasLocationLabel,
|
|
157
157
|
indexingRequestResponseDtoSchema,
|
|
158
158
|
internalError,
|
|
159
|
+
isReadOnlyKey,
|
|
159
160
|
keywordDtoSchema,
|
|
160
161
|
keywordGenerateRequestSchema,
|
|
161
162
|
latestProjectRunDtoSchema,
|
|
@@ -245,7 +246,7 @@ import {
|
|
|
245
246
|
wordpressSchemaDeployResultDtoSchema,
|
|
246
247
|
wordpressSchemaStatusResultDtoSchema,
|
|
247
248
|
wordpressStatusDtoSchema
|
|
248
|
-
} from "./chunk-
|
|
249
|
+
} from "./chunk-KPSFRSS7.js";
|
|
249
250
|
|
|
250
251
|
// src/intelligence-service.ts
|
|
251
252
|
import { eq as eq36, desc as desc17, asc as asc5, and as and26, ne as ne5, or as or5, inArray as inArray13, gte as gte7, lte as lte4 } from "drizzle-orm";
|
|
@@ -5290,6 +5291,7 @@ import fs8 from "fs";
|
|
|
5290
5291
|
// ../api-routes/src/auth.ts
|
|
5291
5292
|
import crypto2 from "crypto";
|
|
5292
5293
|
import { eq } from "drizzle-orm";
|
|
5294
|
+
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
5293
5295
|
function requireScope(request, scope) {
|
|
5294
5296
|
const key = request.apiKey;
|
|
5295
5297
|
if (!key) return;
|
|
@@ -5357,6 +5359,9 @@ async function authPlugin(app, opts = {}) {
|
|
|
5357
5359
|
app.db.update(apiKeys).set({ lastUsedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq(apiKeys.id, key.id)).run();
|
|
5358
5360
|
const scopes = Array.isArray(key.scopes) ? key.scopes : [];
|
|
5359
5361
|
request.apiKey = { id: key.id, name: key.name, scopes };
|
|
5362
|
+
if (isReadOnlyKey(scopes) && WRITE_METHODS.has(request.method)) {
|
|
5363
|
+
throw forbidden("This API key is read-only and cannot perform write operations.");
|
|
5364
|
+
}
|
|
5360
5365
|
});
|
|
5361
5366
|
}
|
|
5362
5367
|
|
|
@@ -14431,6 +14436,17 @@ var routeCatalog = [
|
|
|
14431
14436
|
200: jsonResponse("Keys returned.", "ApiKeyListDto")
|
|
14432
14437
|
}
|
|
14433
14438
|
},
|
|
14439
|
+
{
|
|
14440
|
+
method: "get",
|
|
14441
|
+
path: "/api/v1/keys/self",
|
|
14442
|
+
summary: "Introspect the current API key",
|
|
14443
|
+
description: "Returns SAFE metadata for the key that authenticated this request, including the derived `readOnly` flag. Lets a caller (or the MCP adapter at startup) discover whether its configured key is read-only without listing every key on the instance. Ungated read \u2014 a read-only key can call it.",
|
|
14444
|
+
tags: ["keys"],
|
|
14445
|
+
responses: {
|
|
14446
|
+
200: jsonResponse("Current key returned.", "ApiKeyDto"),
|
|
14447
|
+
404: errorResponse("No key on the request (auth skipped).")
|
|
14448
|
+
}
|
|
14449
|
+
},
|
|
14434
14450
|
{
|
|
14435
14451
|
method: "post",
|
|
14436
14452
|
path: "/api/v1/keys",
|
|
@@ -17586,11 +17602,13 @@ import crypto12 from "crypto";
|
|
|
17586
17602
|
import { desc as desc9, eq as eq17 } from "drizzle-orm";
|
|
17587
17603
|
var KEYS_WRITE_SCOPE = "keys.write";
|
|
17588
17604
|
function toApiKeyDto(row) {
|
|
17605
|
+
const scopes = Array.isArray(row.scopes) ? row.scopes : [];
|
|
17589
17606
|
return {
|
|
17590
17607
|
id: row.id,
|
|
17591
17608
|
name: row.name,
|
|
17592
17609
|
keyPrefix: row.keyPrefix,
|
|
17593
|
-
scopes
|
|
17610
|
+
scopes,
|
|
17611
|
+
readOnly: isReadOnlyKey(scopes),
|
|
17594
17612
|
createdAt: row.createdAt,
|
|
17595
17613
|
lastUsedAt: row.lastUsedAt ?? null,
|
|
17596
17614
|
revokedAt: row.revokedAt ?? null
|
|
@@ -17601,6 +17619,17 @@ async function keysRoutes(app) {
|
|
|
17601
17619
|
const rows = app.db.select().from(apiKeys).orderBy(desc9(apiKeys.createdAt)).all();
|
|
17602
17620
|
return { keys: rows.map(toApiKeyDto) };
|
|
17603
17621
|
});
|
|
17622
|
+
app.get("/keys/self", async (request) => {
|
|
17623
|
+
const id = request.apiKey?.id;
|
|
17624
|
+
if (!id) {
|
|
17625
|
+
throw notFound("API key", "self");
|
|
17626
|
+
}
|
|
17627
|
+
const row = app.db.select().from(apiKeys).where(eq17(apiKeys.id, id)).get();
|
|
17628
|
+
if (!row) {
|
|
17629
|
+
throw notFound("API key", id);
|
|
17630
|
+
}
|
|
17631
|
+
return toApiKeyDto(row);
|
|
17632
|
+
});
|
|
17604
17633
|
app.post("/keys", async (request) => {
|
|
17605
17634
|
requireScope(request, KEYS_WRITE_SCOPE);
|
|
17606
17635
|
const parsed = createApiKeyRequestSchema.safeParse(request.body);
|
|
@@ -17636,6 +17665,7 @@ async function keysRoutes(app) {
|
|
|
17636
17665
|
name,
|
|
17637
17666
|
keyPrefix,
|
|
17638
17667
|
scopes: effectiveScopes,
|
|
17668
|
+
readOnly: isReadOnlyKey(effectiveScopes),
|
|
17639
17669
|
createdAt: now,
|
|
17640
17670
|
lastUsedAt: null,
|
|
17641
17671
|
revokedAt: null,
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
trafficConnectVercelRequestSchema,
|
|
24
24
|
trafficConnectWordpressRequestSchema,
|
|
25
25
|
trafficEventKindSchema
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-KPSFRSS7.js";
|
|
27
27
|
|
|
28
28
|
// src/config.ts
|
|
29
29
|
import fs from "fs";
|
|
@@ -1606,6 +1606,18 @@ var postApiV1Keys = (options) => {
|
|
|
1606
1606
|
}
|
|
1607
1607
|
});
|
|
1608
1608
|
};
|
|
1609
|
+
var getApiV1KeysSelf = (options) => {
|
|
1610
|
+
return (options?.client ?? client).get({
|
|
1611
|
+
security: [
|
|
1612
|
+
{
|
|
1613
|
+
scheme: "bearer",
|
|
1614
|
+
type: "http"
|
|
1615
|
+
}
|
|
1616
|
+
],
|
|
1617
|
+
url: "/api/v1/keys/self",
|
|
1618
|
+
...options
|
|
1619
|
+
});
|
|
1620
|
+
};
|
|
1609
1621
|
var postApiV1KeysByIdRevoke = (options) => {
|
|
1610
1622
|
return (options.client ?? client).post({
|
|
1611
1623
|
security: [
|
|
@@ -4042,6 +4054,10 @@ var ApiClient = class {
|
|
|
4042
4054
|
async listApiKeys() {
|
|
4043
4055
|
return this.invoke(() => getApiV1Keys({ client: this.heyClient }));
|
|
4044
4056
|
}
|
|
4057
|
+
/** Introspect the CURRENT key (the one this client authenticates with). */
|
|
4058
|
+
async getApiKeySelf() {
|
|
4059
|
+
return this.invoke(() => getApiV1KeysSelf({ client: this.heyClient }));
|
|
4060
|
+
}
|
|
4045
4061
|
async createApiKey(body) {
|
|
4046
4062
|
return this.invoke(() => postApiV1Keys({ client: this.heyClient, body }));
|
|
4047
4063
|
}
|
|
@@ -571,6 +571,16 @@ var auditLogEntrySchema = z3.object({
|
|
|
571
571
|
createdAt: z3.string()
|
|
572
572
|
});
|
|
573
573
|
|
|
574
|
+
// ../contracts/src/scopes.ts
|
|
575
|
+
var READ_ONLY_SCOPE = "read";
|
|
576
|
+
var WILDCARD_SCOPE = "*";
|
|
577
|
+
function grantsWrite(scope) {
|
|
578
|
+
return scope === WILDCARD_SCOPE || scope === "write" || scope.endsWith(".write");
|
|
579
|
+
}
|
|
580
|
+
function isReadOnlyKey(scopes) {
|
|
581
|
+
return scopes.includes(READ_ONLY_SCOPE) && !scopes.some(grantsWrite);
|
|
582
|
+
}
|
|
583
|
+
|
|
574
584
|
// ../contracts/src/api-keys.ts
|
|
575
585
|
import { z as z4 } from "zod";
|
|
576
586
|
var apiKeyDtoSchema = z4.object({
|
|
@@ -579,6 +589,13 @@ var apiKeyDtoSchema = z4.object({
|
|
|
579
589
|
/** First 9 chars of the raw token (`cnry_` + 4 hex). Safe to display. */
|
|
580
590
|
keyPrefix: z4.string(),
|
|
581
591
|
scopes: z4.array(z4.string()),
|
|
592
|
+
/**
|
|
593
|
+
* Server-derived convenience flag: `true` when this key is read-only (carries
|
|
594
|
+
* the `read` scope and no write-granting scope), in which case the API rejects
|
|
595
|
+
* every write HTTP method for it. Derived from `scopes` via `isReadOnlyKey`
|
|
596
|
+
* — surfaces don't recompute it (see the UI/CLI parity rule). Additive field.
|
|
597
|
+
*/
|
|
598
|
+
readOnly: z4.boolean(),
|
|
582
599
|
createdAt: z4.string(),
|
|
583
600
|
lastUsedAt: z4.string().nullable(),
|
|
584
601
|
revokedAt: z4.string().nullable()
|
|
@@ -4780,5 +4797,7 @@ export {
|
|
|
4780
4797
|
AI_ENGINE_SELF_DOMAINS,
|
|
4781
4798
|
VERTEX_AI_SEARCH_PROXY_DOMAIN,
|
|
4782
4799
|
AI_PROVIDER_INFRA_DOMAINS,
|
|
4783
|
-
escapeLikePattern
|
|
4800
|
+
escapeLikePattern,
|
|
4801
|
+
READ_ONLY_SCOPE,
|
|
4802
|
+
isReadOnlyKey
|
|
4784
4803
|
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
loadConfigRaw,
|
|
11
11
|
saveConfigPatch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JLAD6CYH.js";
|
|
13
13
|
import {
|
|
14
14
|
CC_CACHE_DIR,
|
|
15
15
|
DUCKDB_SPEC,
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
siteAuditPages,
|
|
105
105
|
siteAuditSnapshots,
|
|
106
106
|
usageCounters
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-IEUTAQUF.js";
|
|
108
108
|
import {
|
|
109
109
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
110
110
|
AGENT_PROVIDER_IDS,
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
validationError,
|
|
161
161
|
winnabilityClassLabel,
|
|
162
162
|
withRetry
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-KPSFRSS7.js";
|
|
164
164
|
|
|
165
165
|
// src/telemetry.ts
|
|
166
166
|
import crypto from "crypto";
|
|
@@ -6278,7 +6278,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6278
6278
|
return result;
|
|
6279
6279
|
}
|
|
6280
6280
|
async function backfillInsightsCommand(project, opts) {
|
|
6281
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6281
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-2UUJ3YGI.js");
|
|
6282
6282
|
const config = loadConfig();
|
|
6283
6283
|
const db = createClient(config.database);
|
|
6284
6284
|
migrate(db);
|
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
setTelemetrySource,
|
|
28
28
|
showFirstRunNotice,
|
|
29
29
|
trackEvent
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-NSZ3D3MM.js";
|
|
31
31
|
import {
|
|
32
32
|
CliError,
|
|
33
33
|
EXIT_SYSTEM_ERROR,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
saveConfig,
|
|
45
45
|
saveConfigPatch,
|
|
46
46
|
usageError
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-JLAD6CYH.js";
|
|
48
48
|
import {
|
|
49
49
|
apiKeys,
|
|
50
50
|
createClient,
|
|
@@ -52,13 +52,14 @@ import {
|
|
|
52
52
|
projects,
|
|
53
53
|
queries,
|
|
54
54
|
renderReportHtml
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-IEUTAQUF.js";
|
|
56
56
|
import {
|
|
57
57
|
BacklinkSources,
|
|
58
58
|
CcReleaseSyncStatuses,
|
|
59
59
|
CheckScopes,
|
|
60
60
|
CheckStatuses,
|
|
61
61
|
CitationStates,
|
|
62
|
+
READ_ONLY_SCOPE,
|
|
62
63
|
RunStatuses,
|
|
63
64
|
TrafficEventKinds,
|
|
64
65
|
backlinkSourceSchema,
|
|
@@ -75,7 +76,7 @@ import {
|
|
|
75
76
|
providerQuotaPolicySchema,
|
|
76
77
|
resolveProviderInput,
|
|
77
78
|
winnabilityClassSchema
|
|
78
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-KPSFRSS7.js";
|
|
79
80
|
|
|
80
81
|
// src/cli.ts
|
|
81
82
|
import { pathToFileURL } from "url";
|
|
@@ -5640,9 +5641,18 @@ async function listApiKeys(format) {
|
|
|
5640
5641
|
}
|
|
5641
5642
|
}
|
|
5642
5643
|
async function createApiKey(opts) {
|
|
5644
|
+
const explicitScopes = opts.scopes && opts.scopes.length > 0 ? opts.scopes : void 0;
|
|
5645
|
+
if (opts.readOnly && explicitScopes) {
|
|
5646
|
+
throw new CliError({
|
|
5647
|
+
code: "CLI_USAGE_ERROR",
|
|
5648
|
+
message: "--read-only cannot be combined with --scope",
|
|
5649
|
+
displayMessage: 'Error: --read-only cannot be combined with --scope (it already implies the "read" scope).'
|
|
5650
|
+
});
|
|
5651
|
+
}
|
|
5643
5652
|
const client = getClient11();
|
|
5644
5653
|
const body = { name: opts.name };
|
|
5645
|
-
|
|
5654
|
+
const scopes = opts.readOnly ? [READ_ONLY_SCOPE] : explicitScopes;
|
|
5655
|
+
if (scopes) body.scopes = scopes;
|
|
5646
5656
|
const created = await client.createApiKey(body);
|
|
5647
5657
|
if (isMachineFormat(opts.format)) {
|
|
5648
5658
|
console.log(JSON.stringify(created, null, 2));
|
|
@@ -5650,11 +5660,24 @@ async function createApiKey(opts) {
|
|
|
5650
5660
|
}
|
|
5651
5661
|
console.log(`API key "${created.name}" created.
|
|
5652
5662
|
`);
|
|
5653
|
-
console.log(` Key:
|
|
5654
|
-
console.log(` Prefix:
|
|
5655
|
-
console.log(` Scopes:
|
|
5663
|
+
console.log(` Key: ${created.key}`);
|
|
5664
|
+
console.log(` Prefix: ${created.keyPrefix}`);
|
|
5665
|
+
console.log(` Scopes: ${created.scopes.join(", ")}`);
|
|
5666
|
+
console.log(` Read-only: ${created.readOnly ? "yes" : "no"}`);
|
|
5656
5667
|
console.log("\nSave this now \u2014 it will not be shown again.");
|
|
5657
5668
|
}
|
|
5669
|
+
async function showApiKeySelf(format) {
|
|
5670
|
+
const client = getClient11();
|
|
5671
|
+
const key = await client.getApiKeySelf();
|
|
5672
|
+
if (isMachineFormat(format)) {
|
|
5673
|
+
console.log(JSON.stringify(key, null, 2));
|
|
5674
|
+
return;
|
|
5675
|
+
}
|
|
5676
|
+
console.log(`API key "${key.name}" (${key.keyPrefix})`);
|
|
5677
|
+
console.log(` Scopes: ${key.scopes.join(", ")}`);
|
|
5678
|
+
console.log(` Read-only: ${key.readOnly ? "yes" : "no"}`);
|
|
5679
|
+
console.log(` Status: ${keyStatus(key)}`);
|
|
5680
|
+
}
|
|
5658
5681
|
async function revokeApiKey(id, format) {
|
|
5659
5682
|
const client = getClient11();
|
|
5660
5683
|
const key = await client.revokeApiKey(id);
|
|
@@ -5676,15 +5699,16 @@ var KEYS_CLI_COMMANDS = [
|
|
|
5676
5699
|
},
|
|
5677
5700
|
{
|
|
5678
5701
|
path: ["key", "create"],
|
|
5679
|
-
usage: "canonry key create --name <name> [--scope <s> ...] [--format json]",
|
|
5702
|
+
usage: "canonry key create --name <name> [--read-only | --scope <s> ...] [--format json]",
|
|
5680
5703
|
options: {
|
|
5681
5704
|
name: stringOption(),
|
|
5682
|
-
scope: multiStringOption()
|
|
5705
|
+
scope: multiStringOption(),
|
|
5706
|
+
"read-only": { type: "boolean" }
|
|
5683
5707
|
},
|
|
5684
5708
|
run: async (input) => {
|
|
5685
5709
|
const name = requireStringOption(input, "name", {
|
|
5686
5710
|
command: "key.create",
|
|
5687
|
-
usage: "canonry key create --name <name> [--scope <s> ...] [--format json]",
|
|
5711
|
+
usage: "canonry key create --name <name> [--read-only | --scope <s> ...] [--format json]",
|
|
5688
5712
|
message: "--name is required"
|
|
5689
5713
|
});
|
|
5690
5714
|
const raw = getStringArray(input.values, "scope") ?? [];
|
|
@@ -5692,10 +5716,18 @@ var KEYS_CLI_COMMANDS = [
|
|
|
5692
5716
|
await createApiKey({
|
|
5693
5717
|
name,
|
|
5694
5718
|
scopes: scopes.length > 0 ? scopes : void 0,
|
|
5719
|
+
readOnly: getBoolean(input.values, "read-only"),
|
|
5695
5720
|
format: input.format
|
|
5696
5721
|
});
|
|
5697
5722
|
}
|
|
5698
5723
|
},
|
|
5724
|
+
{
|
|
5725
|
+
path: ["key", "whoami"],
|
|
5726
|
+
usage: "canonry key whoami [--format json]",
|
|
5727
|
+
run: async (input) => {
|
|
5728
|
+
await showApiKeySelf(input.format);
|
|
5729
|
+
}
|
|
5730
|
+
},
|
|
5699
5731
|
{
|
|
5700
5732
|
path: ["key", "revoke"],
|
|
5701
5733
|
usage: "canonry key revoke <id> [--format json]",
|
|
@@ -5710,12 +5742,12 @@ var KEYS_CLI_COMMANDS = [
|
|
|
5710
5742
|
},
|
|
5711
5743
|
{
|
|
5712
5744
|
path: ["key"],
|
|
5713
|
-
usage: "canonry key <list|create|revoke>",
|
|
5745
|
+
usage: "canonry key <list|create|revoke|whoami>",
|
|
5714
5746
|
run: async (input) => {
|
|
5715
5747
|
unknownSubcommand(input.positionals[0], {
|
|
5716
5748
|
command: "key",
|
|
5717
|
-
usage: "canonry key <list|create|revoke>",
|
|
5718
|
-
available: ["list", "create", "revoke"]
|
|
5749
|
+
usage: "canonry key <list|create|revoke|whoami>",
|
|
5750
|
+
available: ["list", "create", "revoke", "whoami"]
|
|
5719
5751
|
});
|
|
5720
5752
|
}
|
|
5721
5753
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NSZ3D3MM.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-JLAD6CYH.js";
|
|
7
|
+
import "./chunk-IEUTAQUF.js";
|
|
8
|
+
import "./chunk-KPSFRSS7.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,8 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import
|
|
6
|
+
} from "./chunk-JLAD6CYH.js";
|
|
7
|
+
import {
|
|
8
|
+
isReadOnlyKey
|
|
9
|
+
} from "./chunk-KPSFRSS7.js";
|
|
8
10
|
|
|
9
11
|
// src/mcp/cli.ts
|
|
10
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -363,9 +365,25 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
363
365
|
}
|
|
364
366
|
throw error;
|
|
365
367
|
}
|
|
366
|
-
const
|
|
368
|
+
const client = createApiClient();
|
|
369
|
+
const scope = await resolveEffectiveScope(client, options.scope);
|
|
370
|
+
const server = createCanonryMcpServer({ scope, eager: options.eager, clientFactory: () => client });
|
|
367
371
|
await server.connect(new StdioServerTransport());
|
|
368
372
|
}
|
|
373
|
+
async function resolveEffectiveScope(client, flagScope) {
|
|
374
|
+
if (flagScope === "read-only") return "read-only";
|
|
375
|
+
try {
|
|
376
|
+
const self = await client.getApiKeySelf();
|
|
377
|
+
if (isReadOnlyKey(self.scopes)) {
|
|
378
|
+
process.stderr.write(
|
|
379
|
+
"canonry-mcp: configured API key is read-only \u2014 restricting to read tools.\n"
|
|
380
|
+
);
|
|
381
|
+
return "read-only";
|
|
382
|
+
}
|
|
383
|
+
} catch {
|
|
384
|
+
}
|
|
385
|
+
return flagScope;
|
|
386
|
+
}
|
|
369
387
|
function parseCliOptions(argv, env = process.env) {
|
|
370
388
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
371
389
|
throw new HelpRequested();
|
|
@@ -419,5 +437,6 @@ export {
|
|
|
419
437
|
HELP_TEXT,
|
|
420
438
|
HelpRequested,
|
|
421
439
|
main,
|
|
422
|
-
parseCliOptions
|
|
440
|
+
parseCliOptions,
|
|
441
|
+
resolveEffectiveScope
|
|
423
442
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.82.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -62,27 +62,27 @@
|
|
|
62
62
|
"@types/node-cron": "^3.0.11",
|
|
63
63
|
"tsup": "^8.5.1",
|
|
64
64
|
"tsx": "^4.19.0",
|
|
65
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
66
65
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
66
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
67
67
|
"@ainyc/canonry-config": "0.0.0",
|
|
68
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
69
68
|
"@ainyc/canonry-db": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
71
71
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
72
|
-
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
73
72
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
73
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
74
74
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
75
75
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
76
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
77
76
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
78
|
-
"@ainyc/canonry-integration-
|
|
77
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
78
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
80
81
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
81
82
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
82
|
-
"@ainyc/canonry-intelligence": "0.0.0",
|
|
83
83
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-provider-
|
|
85
|
-
"@ainyc/canonry-provider-
|
|
84
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
85
|
+
"@ainyc/canonry-provider-openai": "0.0.0"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|