@extenshi/mcp 0.12.0 → 0.13.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.
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Compact reads of the hosted landing page (DX report 2026-10-10 §2 row 15).
3
+ *
4
+ * `get_landing_page` returns the form the live version was rendered from. With
5
+ * eleven locales and an inline logo that form is ~80 KB — more than an MCP
6
+ * response carries. So the tool answers with a summary by default (what is
7
+ * live, which locales and sections exist, how big each part is) and returns
8
+ * the form only on request, optionally narrowed to some top-level fields and
9
+ * some translations.
10
+ *
11
+ * Shaped here, from the response the BFF already sends, rather than in the BFF:
12
+ * every BFF version returns the same full form, so this works against an old
13
+ * BFF and a new one alike, and the BFF contract does not change.
14
+ */
15
+ import { z } from 'zod';
16
+ import { normalizeLandingLocale } from './landing-sections.js';
17
+ export const LANDING_READ_VIEWS = ['summary', 'full'];
18
+ /** get_landing_page parameters besides projectId. */
19
+ export const LANDING_READ_SHAPE = {
20
+ view: z
21
+ .enum(LANDING_READ_VIEWS)
22
+ .optional()
23
+ .describe('"summary" (default): what is live and how big each part of the form is. "full": the form itself.'),
24
+ fields: z
25
+ .array(z.string().max(40))
26
+ .max(40)
27
+ .optional()
28
+ .describe('With view "full": top-level form keys to return, e.g. ["sections", "seo"] (names and sizes are in formSummary.fields). Default: all.'),
29
+ locales: z
30
+ .array(z.string().max(35))
31
+ .max(100)
32
+ .optional()
33
+ .describe('With view "full": translations to keep in form.locales, e.g. ["de"]; [] drops them all. The base content is part of every full read.'),
34
+ };
35
+ const isObject = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
36
+ const bytesOf = (value) => value === undefined ? 0 : new TextEncoder().encode(JSON.stringify(value)).length;
37
+ const LINK_FIELDS = [
38
+ 'homepageUrl',
39
+ 'chromeUrl',
40
+ 'firefoxUrl',
41
+ 'edgeUrl',
42
+ 'privacyPolicyUrl',
43
+ 'supportUrl',
44
+ 'uninstallUrl',
45
+ 'termsUrl',
46
+ ];
47
+ /** `bytes` is measured like every other size here: the field as JSON (quotes included). */
48
+ function logoOf(form) {
49
+ if (typeof form.logoSvg === 'string' && form.logoSvg)
50
+ return { kind: 'svg', bytes: bytesOf(form.logoSvg) };
51
+ if (typeof form.logoUrl === 'string' && form.logoUrl)
52
+ return { kind: form.logoUrl.startsWith('data:') ? 'data-url' : 'url', bytes: bytesOf(form.logoUrl) };
53
+ return { kind: 'none', bytes: 0 };
54
+ }
55
+ /** What an agent decides from before asking for the form itself. */
56
+ export function summarizeLandingForm(form) {
57
+ const sections = Array.isArray(form.sections) ? form.sections : [];
58
+ const locales = isObject(form.locales) ? form.locales : {};
59
+ const links = Object.fromEntries(LINK_FIELDS.flatMap((key) => (typeof form[key] === 'string' && form[key] ? [[key, form[key]]] : [])));
60
+ return {
61
+ bytes: bytesOf(form),
62
+ schemaVersion: form.schemaVersion ?? 1,
63
+ extensionName: form.extensionName,
64
+ tagline: form.tagline,
65
+ theme: form.theme,
66
+ accentColor: form.accentColor,
67
+ defaultLocale: normalizeLandingLocale(form.defaultLocale) ?? 'en',
68
+ translations: Object.entries(locales).map(([locale, content]) => ({ locale, bytes: bytesOf(content) })),
69
+ sections: sections.map((section, index) => {
70
+ const s = isObject(section) ? section : {};
71
+ return {
72
+ index,
73
+ id: s.id,
74
+ type: s.type,
75
+ ...(s.hidden ? { hidden: true } : {}),
76
+ bytes: bytesOf(section),
77
+ };
78
+ }),
79
+ links,
80
+ logo: logoOf(form),
81
+ features: Array.isArray(form.features) ? form.features.length : 0,
82
+ screenshots: Array.isArray(form.screenshots) ? form.screenshots.length : 0,
83
+ // Largest first: the parts worth leaving out of a full read.
84
+ fields: Object.keys(form)
85
+ .map((field) => ({ field, bytes: bytesOf(form[field]) }))
86
+ .sort((a, b) => b.bytes - a.bytes),
87
+ };
88
+ }
89
+ function narrowForm(form, fields, locales) {
90
+ let out = form;
91
+ if (fields?.length) {
92
+ // schemaVersion decides how the rest reads, so it always comes along; asking
93
+ // for translations by `locales` keeps `locales` even when `fields` omits it.
94
+ const keep = new Set([...fields, 'schemaVersion', ...(locales ? ['locales'] : [])]);
95
+ out = Object.fromEntries(Object.entries(out).filter(([key]) => keep.has(key)));
96
+ }
97
+ if (locales && isObject(out.locales)) {
98
+ const wanted = new Set(locales.map((l) => normalizeLandingLocale(l) ?? l));
99
+ out = {
100
+ ...out,
101
+ locales: Object.fromEntries(Object.entries(out.locales).filter(([key]) => wanted.has(normalizeLandingLocale(key) ?? key))),
102
+ };
103
+ }
104
+ return out;
105
+ }
106
+ /**
107
+ * Shape a `getLandingPage` response for the agent. Anything that is not the
108
+ * expected `{ page, url, form }` object passes through untouched.
109
+ */
110
+ export function shapeLandingRead(result, options = {}) {
111
+ if (!isObject(result) || !('form' in result))
112
+ return result;
113
+ const form = isObject(result.form) ? result.form : null;
114
+ if ((options.view ?? 'summary') === 'full') {
115
+ const narrowed = form ? narrowForm(form, options.fields, options.locales) : result.form;
116
+ return {
117
+ ...result,
118
+ form: narrowed,
119
+ ...(form && narrowed !== form
120
+ ? { formBytes: { full: bytesOf(form), returned: bytesOf(narrowed) } }
121
+ : {}),
122
+ };
123
+ }
124
+ const { form: _form, ...rest } = result;
125
+ return {
126
+ ...rest,
127
+ view: 'summary',
128
+ formSummary: form ? summarizeLandingForm(form) : null,
129
+ ...(form
130
+ ? {
131
+ next: 'Pass view "full" for the form; add fields (top-level keys from formSummary.fields) and locales to read only part of it.',
132
+ }
133
+ : {}),
134
+ };
135
+ }
136
+ //# sourceMappingURL=landing-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"landing-read.js","sourceRoot":"","sources":["../src/landing-read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Read-only license terms tools (DX report 2026-10-10 §2 row 16).
3
+ *
4
+ * Without pay.read an agent could not see the "License terms & refunds"
5
+ * questionnaire at all; it existed only in the Dojo card. These two tools give
6
+ * it the questions and an unsaved draft from its own answers, under project
7
+ * read access. They carry no saved answers (the seller's legal name, address
8
+ * and registration live there) and no Pay state, which is what keeps them off
9
+ * pay.read; saving and publishing stay with the owner in Dojo.
10
+ */
11
+ import type { FastMCPSessionAuth, Tool, ToolParameters } from 'fastmcp';
12
+ import type { Bff } from './bff.js';
13
+ import type { ToolCallContext } from './tools.js';
14
+ type AddTool = <P extends ToolParameters>(tool: Tool<FastMCPSessionAuth, P>) => void;
15
+ export declare function registerLicenseTermsTools(add: AddTool, bff: (context: ToolCallContext) => Bff, fail: (err: unknown) => never): void;
16
+ export {};
17
+ //# sourceMappingURL=license-terms-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-terms-tools.d.ts","sourceRoot":"","sources":["../src/license-terms-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,KAAK,OAAO,GAAG,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAA;AAIpF,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,GAAG,EACtC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,GAC3B,IAAI,CA4CN"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Read-only license terms tools (DX report 2026-10-10 §2 row 16).
3
+ *
4
+ * Without pay.read an agent could not see the "License terms & refunds"
5
+ * questionnaire at all; it existed only in the Dojo card. These two tools give
6
+ * it the questions and an unsaved draft from its own answers, under project
7
+ * read access. They carry no saved answers (the seller's legal name, address
8
+ * and registration live there) and no Pay state, which is what keeps them off
9
+ * pay.read; saving and publishing stay with the owner in Dojo.
10
+ */
11
+ import { z } from 'zod';
12
+ const READ_ONLY = { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: true };
13
+ export function registerLicenseTermsTools(add, bff, fail) {
14
+ add({
15
+ name: 'get_license_terms_questionnaire',
16
+ description: 'The questions of the project\'s "License terms & refunds" questionnaire as data: field, question, ' +
17
+ 'type, choices, length and number limits, and when each answer is required before the owner can ' +
18
+ 'publish. Questions only: it returns no saved answers, seller or Pay state, so project read access ' +
19
+ 'is enough (no pay.read). Pair it with draft_license_terms. FREE.',
20
+ parameters: z.object({ projectId: z.string().uuid() }),
21
+ annotations: { title: 'Read the license terms questionnaire', ...READ_ONLY },
22
+ execute: async (args, context) => {
23
+ try {
24
+ return JSON.stringify(await bff(context).getLicenseTermsQuestionnaire(args));
25
+ }
26
+ catch (err) {
27
+ return fail(err);
28
+ }
29
+ },
30
+ });
31
+ add({
32
+ name: 'draft_license_terms',
33
+ description: 'Generate the license terms & refunds text from answers supplied in the call, without saving ' +
34
+ 'anything: the markdown the owner would publish, the unanswered questions that block publishing, ' +
35
+ 'and the normalized answers. An empty extensionName takes the project name. Saved answers, the ' +
36
+ 'seller and Pay offers are not read (they need pay.read), so plan types the seller sells are not ' +
37
+ 'cross-checked here; Dojo checks them when the owner saves and publishes. FREE.',
38
+ parameters: z.object({
39
+ projectId: z.string().uuid(),
40
+ answers: z
41
+ .record(z.unknown())
42
+ .optional()
43
+ .describe('Answers keyed by the field names get_license_terms_questionnaire lists, e.g. {"sellerCountry": "Spain", "planKinds": ["lifetime"], "refundPolicy": "window", "refundWindowDays": 14}. Omitted fields count as unanswered.'),
44
+ }),
45
+ annotations: { title: 'Draft license terms from answers', ...READ_ONLY },
46
+ execute: async (args, context) => {
47
+ try {
48
+ return JSON.stringify(await bff(context).draftLicenseTerms(args));
49
+ }
50
+ catch (err) {
51
+ return fail(err);
52
+ }
53
+ },
54
+ });
55
+ }
56
+ //# sourceMappingURL=license-terms-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-terms-tools.js","sourceRoot":"","sources":["../src/license-terms-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,MAAM,SAAS,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAA;AAE3G,MAAM,UAAU,yBAAyB,CACxC,GAAY,EACZ,GAAsC,EACtC,IAA6B;IAE7B,GAAG,CAAC;QACH,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACV,oGAAoG;YACpG,iGAAiG;YACjG,oGAAoG;YACpG,kEAAkE;QACnE,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QACtD,WAAW,EAAE,EAAE,KAAK,EAAE,sCAAsC,EAAE,GAAG,SAAS,EAAE;QAC5E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAChC,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAA;YAC7E,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;YACjB,CAAC;QACF,CAAC;KACD,CAAC,CAAA;IACF,GAAG,CAAC;QACH,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACV,8FAA8F;YAC9F,kGAAkG;YAClG,gGAAgG;YAChG,kGAAkG;YAClG,gFAAgF;QACjF,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;YAC5B,OAAO,EAAE,CAAC;iBACR,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;iBACnB,QAAQ,EAAE;iBACV,QAAQ,CACR,2NAA2N,CAC3N;SACF,CAAC;QACF,WAAW,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,GAAG,SAAS,EAAE;QACxE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAChC,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAA;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;YACjB,CAAC;QACF,CAAC;KACD,CAAC,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AASH,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,SAAS,CAAA;AAG1G,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AA2DnC,eAAO,MAAM,QAAQ,sCAAsC,CAAA;AAC3D,eAAO,MAAM,WAAW,oCAAoC,CAAA;AAC5D,eAAO,MAAM,YAAY,qCAAqC,CAAA;AAC9D,eAAO,MAAM,iBAAiB,+EAA+E,CAAA;AAO7G,eAAO,MAAM,mBAAmB,QAWS,CAAA;AAEzC;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC,eAAO,MAAM,WAAW,aAAa,CAAA;AAErC,eAAO,MAAM,mBAAmB,QAmBmB,CAAA;AAEnD,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,GAAG,MAAM,CAWnF;AAID,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC5B;AAED,MAAM,WAAW,QAAQ;IACxB,kEAAkE;IAClE,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,+BAA+B;IAC/B,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IACrC;;;;;OAKG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,GAAG,CAAA;IACrC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAA;IAChD;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,GAAG,SAAS,CAAA;IACxD,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAiFD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,MAA2B,GAAG,OAAO,CAGxF;AAsuBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAqxDnE"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AASH,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,kBAAkB,EAA6C,MAAM,SAAS,CAAA;AAG1G,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AA6DnC,eAAO,MAAM,QAAQ,sCAAsC,CAAA;AAC3D,eAAO,MAAM,WAAW,oCAAoC,CAAA;AAC5D,eAAO,MAAM,YAAY,qCAAqC,CAAA;AAC9D,eAAO,MAAM,iBAAiB,+EAA+E,CAAA;AAO7G,eAAO,MAAM,mBAAmB,QAWS,CAAA;AAEzC;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC,eAAO,MAAM,WAAW,aAAa,CAAA;AAErC,eAAO,MAAM,mBAAmB,QAmBmB,CAAA;AAEnD,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,GAAG,MAAM,CAWnF;AAID,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC5B;AAED,MAAM,WAAW,QAAQ;IACxB,kEAAkE;IAClE,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,+BAA+B;IAC/B,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IACrC;;;;;OAKG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,GAAG,CAAA;IACrC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAA;IAChD;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,GAAG,SAAS,CAAA;IACxD,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAiFD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,MAA2B,GAAG,OAAO,CAGxF;AAsuBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAsyDnE"}
package/dist/tools.js CHANGED
@@ -40,8 +40,10 @@ import { buildDevelopmentGuide, GUIDE_SECTIONS } from './development-guide.js';
40
40
  import { DEFAULT_EXCERPT_CHARS, DocsError, getDocsIndex, MAX_EXCERPT_CHARS, MIN_EXCERPT_CHARS, searchDocs, } from './docs.js';
41
41
  import { renderIconWorkflow } from './icon-workflow.js';
42
42
  import { LANDING_LIMITS } from './landing-page.js';
43
+ import { LANDING_READ_SHAPE, shapeLandingRead } from './landing-read.js';
43
44
  import { LANDING_FONTS, LANDING_SECTION_TYPES, LANDING_UI_DEFAULTS, LANDING_V2_LIMITS, } from './landing-sections.js';
44
45
  import { hostedLandingNextSteps, landingFormFromArgs, renderGenerateLandingPage } from './landing-workflow.js';
46
+ import { registerLicenseTermsTools } from './license-terms-tools.js';
45
47
  import { renderLocalizeWorkflow } from './localize-workflow.js';
46
48
  import { PAY_OPERATIONS, paySchemas } from './pay.js';
47
49
  import { describePrivacyAiUpdate } from './privacy-ai-outcome.js';
@@ -1243,11 +1245,16 @@ export function registerTools(server, deps) {
1243
1245
  add({
1244
1246
  name: 'get_landing_page',
1245
1247
  description: "The project's hosted landing page: public code, live version, publish state, URL (null when " +
1246
- 'unpublished) and the form the live version was rendered from.',
1247
- parameters: z.object({ projectId: z.string().uuid() }),
1248
- execute: async (args, context) => {
1248
+ 'unpublished) and the form the live version was rendered from. By default the form comes as a ' +
1249
+ 'summary (locales, sections, links, logo, size of each field); view "full" returns the form, ' +
1250
+ 'narrowed by fields and locales when given.',
1251
+ parameters: z.object({
1252
+ projectId: z.string().uuid(),
1253
+ ...LANDING_READ_SHAPE,
1254
+ }),
1255
+ execute: async ({ projectId, ...options }, context) => {
1249
1256
  try {
1250
- return JSON.stringify(await bff(context).getLandingPage(args));
1257
+ return JSON.stringify(shapeLandingRead(await bff(context).getLandingPage({ projectId }), options));
1251
1258
  }
1252
1259
  catch (err) {
1253
1260
  return readError(err, missingKeyMessage);
@@ -1612,6 +1619,8 @@ export function registerTools(server, deps) {
1612
1619
  }
1613
1620
  },
1614
1621
  });
1622
+ // get_license_terms_questionnaire / draft_license_terms (project.read, read-only).
1623
+ registerLicenseTermsTools(add, bff, (err) => readError(err, missingKeyMessage));
1615
1624
  // A local filesystem exists only where local artifacts do (stdio).
1616
1625
  const localFiles = caps.has('scan');
1617
1626
  add({
@@ -2092,21 +2101,29 @@ export function registerTools(server, deps) {
2092
2101
  'site then stops managing the values in it. `integration.unwired` lists the links this ' +
2093
2102
  'project has not set up yet (no URLs exist for them). Tool-state payloads are NOT inlined by ' +
2094
2103
  'default (a single row can be 256 KiB); includeToolStates selects which keys to inline. ' +
2095
- 'FREE — spends no credit. Type definitions are in list_extension_templates.',
2104
+ 'Manifests come as summaries by default (version, top-level keys, size, digest, origin ' +
2105
+ 'imported/generated, and which keys of each drafted manifest differ from the imported ' +
2106
+ 'source/built one); pass manifests "full" for the bodies, or get_project_scaffold for one ' +
2107
+ "browser's manifest file. FREE — spends no credit. Type definitions are in list_extension_templates.",
2096
2108
  parameters: z.object({
2097
2109
  projectId: z.string().describe('Project id from list_my_projects.'),
2098
2110
  includeToolStates: z
2099
2111
  .array(z.string())
2100
2112
  .optional()
2101
2113
  .describe('Tool keys whose saved payload to inline, e.g. ["manifest-generator", "privacy-policy-generator"]. When omitted, only the index is returned.'),
2114
+ manifests: z
2115
+ .enum(['summary', 'full'])
2116
+ .optional()
2117
+ .describe('"summary" (default): each manifest as version, keys, size and digest — the same digest release.manifestDigest (built) and release.sourceManifestDigest (source) carry. "full": the drafted manifests and the imported source/built manifests in full (can be ~60 KB).'),
2102
2118
  }),
2103
2119
  execute: async (args, context) => {
2104
2120
  try {
2105
2121
  const state = await bff(context).getMyProjectState({
2106
2122
  projectId: args.projectId,
2107
2123
  includeToolStates: args.includeToolStates,
2124
+ manifests: args.manifests ?? 'summary',
2108
2125
  });
2109
- return JSON.stringify(state, null, 2);
2126
+ return JSON.stringify(state);
2110
2127
  }
2111
2128
  catch (err) {
2112
2129
  return readError(err, missingKeyMessage);