@unbrained/pm-cli 2026.8.25 → 2026.8.27
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/.agents/skills/HARNESS_COMPATIBILITY.md +32 -0
- package/.agents/skills/README.md +47 -0
- package/.agents/skills/pm-developer/SKILL.md +117 -0
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +49 -0
- package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +91 -0
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +72 -0
- package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-developer/references/SCRIPTING_COMPOSITION.md +82 -0
- package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +85 -0
- package/.agents/skills/pm-extensions/SKILL.md +106 -0
- package/.agents/skills/pm-extensions/references/AUTHORING.md +95 -0
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
- package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
- package/.agents/skills/pm-sdk/SKILL.md +107 -0
- package/.agents/skills/pm-sdk/references/DOMAIN_MODELING.md +78 -0
- package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
- package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
- package/.agents/skills/pm-sdk/references/SURFACE_MAP.md +82 -0
- package/.agents/skills/pm-user/SKILL.md +111 -0
- package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +105 -0
- package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +58 -3
- package/README.md +8 -5
- package/dist/cli/commander-usage.js +11 -7
- package/dist/cli/error-guidance.js +3 -3
- package/dist/cli/help-content.d.ts +2 -0
- package/dist/cli/help-content.js +53 -17
- package/dist/cli/help-json-payload.d.ts +8 -2
- package/dist/cli/help-json-payload.js +46 -12
- package/dist/cli/main.js +52 -74
- package/dist/cli/register-annotations.js +27 -21
- package/dist/cli/register-setup.js +98 -57
- package/dist/cli-bundle/bundle-manifest.json +156 -156
- package/dist/cli-bundle/chunks/chunk-3OO3W6FW.js +202 -0
- package/dist/cli-bundle/chunks/chunk-52EKTW6V.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-QLUORNIB.js → chunk-CVBBGWW5.js} +62 -44
- package/dist/cli-bundle/chunks/chunk-MFNTKMTI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-OS27HHBN.js +35 -0
- package/dist/cli-bundle/chunks/chunk-QTO7USTH.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-5I5RWIJC.js → chunk-R4ETAOJC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OWHNAR2B.js → chunk-SH6P7FXI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SHMDY36D.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-244MI4GS.js → chunk-SKXLJIEK.js} +60 -60
- package/dist/cli-bundle/chunks/chunk-TNX6HC54.js +3 -0
- package/dist/cli-bundle/chunks/{register-list-query-XVN2ZLI7.js → register-list-query-EUWM6VII.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-QCKAEGIJ.js → register-mutation-FD4HSAVU.js} +4 -4
- package/dist/cli-bundle/chunks/{register-operations-SDEAXE7E.js → register-operations-HRMNFEC3.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-33GNICLX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IBZZZGK3.js → chunk-2AGZ5BRT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4BR5UU52.js +50 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OHIHZ7HS.js → chunk-6GCRSLPG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OVJL6NZE.js → chunk-AD6ULRAF.js} +4 -4
- package/dist/cli-bundle/focused-chunks/{chunk-7YCDTCBC.js → chunk-AQ5IYEZZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YO3ZF3FI.js → chunk-EKX37ZHA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-N7W67YIG.js → chunk-FC2AXLB5.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-H5JZEIQV.js → chunk-HC7ODMH3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NOOZGIXP.js → chunk-HVQ22RC4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-A644DUFQ.js → chunk-MEASX544.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RAFKLNZX.js → chunk-MXTYGECH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2UIWOP3O.js → chunk-SUBSWYW3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VXWATRFL.js → chunk-XDPYBQCF.js} +9 -9
- package/dist/cli-bundle/focused-chunks/{chunk-XUQPEKRN.js → chunk-Y3JJXRVK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GQR3WH3F.js → chunk-Y5A7SJJ7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-YHWHX6YY.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ONYQCALA.js → chunk-YVVZ3LQ6.js} +6 -6
- package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +5 -0
- package/dist/cli-bundle/main.js +15 -14
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +31 -31
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +31 -31
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +32 -6
- package/dist/core/extensions/manifest-schema.d.ts +20 -0
- package/dist/core/extensions/manifest-schema.js +28 -10
- package/dist/core/governance/issue-codes.d.ts +11 -2
- package/dist/core/governance/issue-codes.js +29 -10
- package/dist/core/item/item-format.js +3 -3
- package/dist/core/store/item-store.js +12 -5
- package/dist/mcp/http-server.d.ts +60 -0
- package/dist/mcp/http-server.js +451 -0
- package/dist/mcp/legacy-adapter.d.ts +50 -0
- package/dist/mcp/legacy-adapter.js +64 -0
- package/dist/mcp/server.d.ts +42 -9
- package/dist/mcp/server.js +572 -59
- package/dist/mcp/tool-definitions.d.ts +2 -0
- package/dist/mcp/tool-definitions.js +2 -2
- package/dist/sdk/agent/closed-domain-contracts.d.ts +1 -1
- package/dist/sdk/agent/closed-domain-contracts.js +24 -2
- package/dist/sdk/agent/refusal-closure-census.d.ts +6 -2
- package/dist/sdk/agent/refusal-closure-census.js +16 -8
- package/dist/sdk/agent-capability-contracts.js +6 -2
- package/dist/sdk/cli-bootstrap.js +3 -2
- package/dist/sdk/cli-contracts/command-aliases.js +15 -2
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -5
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +3 -3
- package/dist/sdk/cli-contracts/grammar-contracts.js +24 -17
- package/dist/sdk/cli-contracts/runtime-contracts.js +13 -11
- package/dist/sdk/cli-contracts/tool-schema.js +18 -15
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/cli-program.js +3 -2
- package/dist/sdk/completion.js +40 -13
- package/dist/sdk/compose.d.ts +4 -1
- package/dist/sdk/compose.js +23 -36
- package/dist/sdk/extension/author-manifest.d.ts +22 -0
- package/dist/sdk/extension/author-manifest.js +93 -0
- package/dist/sdk/extension.js +6 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +20 -5
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +18 -3
- package/dist/sdk/governance/health.js +7 -2
- package/dist/sdk/governance/upgrade.d.ts +2 -0
- package/dist/sdk/governance/upgrade.js +30 -8
- package/dist/sdk/governance/validate.js +8 -6
- package/dist/sdk/guide-topics.js +6 -6
- package/dist/sdk/index.d.ts +10 -2
- package/dist/sdk/index.js +11 -3
- package/dist/sdk/mcp/apps.d.ts +70 -0
- package/dist/sdk/mcp/apps.js +154 -0
- package/dist/sdk/mcp/authorization.d.ts +134 -0
- package/dist/sdk/mcp/authorization.js +405 -0
- package/dist/sdk/mcp/interactions.d.ts +118 -0
- package/dist/sdk/mcp/interactions.js +337 -0
- package/dist/sdk/mcp/protocol.d.ts +142 -0
- package/dist/sdk/mcp/protocol.js +174 -0
- package/dist/sdk/mcp/skills.d.ts +127 -0
- package/dist/sdk/mcp/skills.js +390 -0
- package/dist/sdk/mcp/subscriptions.d.ts +65 -0
- package/dist/sdk/mcp/subscriptions.js +212 -0
- package/dist/sdk/mcp/tasks.d.ts +107 -0
- package/dist/sdk/mcp/tasks.js +431 -0
- package/dist/sdk/mcp/transport.d.ts +30 -0
- package/dist/sdk/mcp/transport.js +261 -0
- package/dist/sdk/merge/receipts.d.ts +16 -0
- package/dist/sdk/merge/receipts.js +9 -8
- package/dist/sdk/read-output-contracts.js +16 -3
- package/dist/sdk/runtime-action-aliases.js +7 -3
- package/dist/sdk/runtime-input.js +12 -4
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +4 -4
- package/dist/sdk/test/execution.d.ts +6 -0
- package/dist/sdk/test/execution.js +32 -3
- package/docs/AGENT_PROVENANCE_ADR.md +6 -4
- package/docs/AGENT_RUNTIME_PRIMITIVES.md +6 -5
- package/docs/CLAUDE_CODE_PLUGIN.md +12 -5
- package/docs/CLI_GRAMMAR.md +7 -1
- package/docs/COMMANDS.md +2 -2
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +8 -0
- package/docs/EXTENSIONS.md +36 -36
- package/docs/MCP_2026_07_28.md +160 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +30 -0
- package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +180 -0
- package/docs/MCP_SKILLS_AND_APPS.md +107 -0
- package/docs/QUICKSTART.md +15 -15
- package/docs/README.md +5 -0
- package/docs/RELEASING.md +12 -3
- package/docs/SDK.md +22 -1
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +18 -13
- package/docs/SDK_CONTEXT_INTEGRITY.md +6 -0
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +9 -1
- package/docs/SDK_MCP_INTERACTIONS.md +227 -0
- package/docs/TESTING.md +4 -0
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -11
- package/marketplace.json +2 -2
- package/package.json +15 -11
- package/packages/pm-beads/README.md +12 -6
- package/packages/pm-beads/docs/MIGRATION.md +53 -0
- package/packages/pm-beads/extensions/beads/index.ts +8 -0
- package/packages/pm-beads/extensions/beads/runtime.ts +671 -112
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/scripts/finalize-build.mjs +1 -0
- package/sdk/public-surface.json +902 -54
- package/dist/cli-bundle/chunks/chunk-2F3LUFMW.js +0 -8
- package/dist/cli-bundle/chunks/chunk-65MHLHAA.js +0 -2
- package/dist/cli-bundle/chunks/chunk-6C7GIMIL.js +0 -13
- package/dist/cli-bundle/chunks/chunk-QKGMHGEI.js +0 -202
- package/dist/cli-bundle/chunks/chunk-T2ENPRXF.js +0 -3
- package/dist/cli-bundle/chunks/chunk-TPQIBSL2.js +0 -3
- package/dist/cli-bundle/chunks/chunk-YQMYF3YD.js +0 -35
- package/dist/cli-bundle/chunks/register-setup-LXVBRCJ3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-42S3GGZ7.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-7I23XGWO.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +0 -5
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e6c49c89-781e-59a3-9c19-6a1c40424587")}catch(e){}}();
|
|
3
|
+
import { PM_MCP_ERROR_CODES, PmMcpProtocolError, isMcpRecord, } from "./protocol.js";
|
|
4
|
+
/** Stable MCP Apps extension identifier. */
|
|
5
|
+
export const PM_MCP_APPS_EXTENSION = "io.modelcontextprotocol/ui";
|
|
6
|
+
/** Stable MCP Apps specification revision implemented by pm. */
|
|
7
|
+
export const PM_MCP_APPS_SPEC_VERSION = "2026-01-26";
|
|
8
|
+
/** Official MIME type for MCP App HTML resources. */
|
|
9
|
+
export const PM_MCP_APP_MIME_TYPE = "text/html;profile=mcp-app";
|
|
10
|
+
/** Server-side MCP Apps capability advertised through discovery. */
|
|
11
|
+
export const PM_MCP_APPS_SERVER_CAPABILITY = Object.freeze({
|
|
12
|
+
specVersion: PM_MCP_APPS_SPEC_VERSION,
|
|
13
|
+
mimeTypes: [PM_MCP_APP_MIME_TYPE],
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Resolve whether a request negotiated MCP Apps, rejecting malformed explicit
|
|
17
|
+
* declarations instead of silently serving a different extension revision.
|
|
18
|
+
*/
|
|
19
|
+
export function hasPmMcpAppsCapability(context) {
|
|
20
|
+
const extensions = context.clientCapabilities.extensions;
|
|
21
|
+
if (!isMcpRecord(extensions))
|
|
22
|
+
return false;
|
|
23
|
+
const declaration = extensions[PM_MCP_APPS_EXTENSION];
|
|
24
|
+
if (declaration === undefined)
|
|
25
|
+
return false;
|
|
26
|
+
if (!isMcpRecord(declaration)) {
|
|
27
|
+
throw new PmMcpProtocolError("Invalid MCP Apps client capability", PM_MCP_ERROR_CODES.missingRequiredClientCapability, { requiredCapabilities: { extensions: { [PM_MCP_APPS_EXTENSION]: PM_MCP_APPS_SERVER_CAPABILITY } } });
|
|
28
|
+
}
|
|
29
|
+
const mimeTypes = declaration.mimeTypes;
|
|
30
|
+
const specVersion = declaration.specVersion;
|
|
31
|
+
if (!Array.isArray(mimeTypes) ||
|
|
32
|
+
!mimeTypes.includes(PM_MCP_APP_MIME_TYPE) ||
|
|
33
|
+
(specVersion !== undefined && specVersion !== PM_MCP_APPS_SPEC_VERSION)) {
|
|
34
|
+
throw new PmMcpProtocolError("Unsupported MCP Apps client capability", PM_MCP_ERROR_CODES.missingRequiredClientCapability, { requiredCapabilities: { extensions: { [PM_MCP_APPS_EXTENSION]: PM_MCP_APPS_SERVER_CAPABILITY } } });
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const PRIVATE_APP_RESOURCE_META = {
|
|
39
|
+
csp: { connectDomains: [], resourceDomains: [], frameDomains: [] },
|
|
40
|
+
permissions: {},
|
|
41
|
+
prefersBorder: true,
|
|
42
|
+
};
|
|
43
|
+
/** Canonical optional pm MCP Apps. */
|
|
44
|
+
export const PM_MCP_APP_CONTRACTS = Object.freeze([
|
|
45
|
+
{
|
|
46
|
+
id: "context",
|
|
47
|
+
name: "Context explorer",
|
|
48
|
+
description: "Inspect bounded project context, provenance, omissions, and token accounting.",
|
|
49
|
+
toolName: "pm_context",
|
|
50
|
+
uri: "ui://pm/context.html",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "graph",
|
|
54
|
+
name: "Relationship graph",
|
|
55
|
+
description: "Explore typed relationships, explaining paths, and graph-governance evidence.",
|
|
56
|
+
toolName: "pm_graph",
|
|
57
|
+
uri: "ui://pm/graph.html",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "plan",
|
|
61
|
+
name: "Plan and milestone view",
|
|
62
|
+
description: "Review durable plan steps, dependencies, decisions, discoveries, and validation state.",
|
|
63
|
+
toolName: "pm_plan",
|
|
64
|
+
uri: "ui://pm/plan.html",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "assurance",
|
|
68
|
+
name: "Assurance dashboard",
|
|
69
|
+
description: "Inspect validation verdicts, evidence, omissions, and actionable recovery paths.",
|
|
70
|
+
toolName: "pm_validate",
|
|
71
|
+
uri: "ui://pm/assurance.html",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "operations",
|
|
75
|
+
name: "Long-operation view",
|
|
76
|
+
description: "Inspect durable test and operation results without creating a second task store.",
|
|
77
|
+
toolName: "pm_test",
|
|
78
|
+
uri: "ui://pm/operations.html",
|
|
79
|
+
},
|
|
80
|
+
].map((contract) => ({
|
|
81
|
+
...contract,
|
|
82
|
+
toolMeta: {
|
|
83
|
+
resourceUri: contract.uri,
|
|
84
|
+
visibility: ["model", "app"],
|
|
85
|
+
},
|
|
86
|
+
resourceMeta: PRIVATE_APP_RESOURCE_META,
|
|
87
|
+
})));
|
|
88
|
+
/** Return the app contract for a resource URI. */
|
|
89
|
+
export function findPmMcpAppByUri(uri) {
|
|
90
|
+
return PM_MCP_APP_CONTRACTS.find((contract) => contract.uri === uri);
|
|
91
|
+
}
|
|
92
|
+
/** Attach negotiated MCP App metadata to matching tool definitions. */
|
|
93
|
+
export function decoratePmMcpToolsWithApps(tools) {
|
|
94
|
+
const appsByTool = new Map(PM_MCP_APP_CONTRACTS.map((contract) => [contract.toolName, contract]));
|
|
95
|
+
return tools.map((tool) => {
|
|
96
|
+
const app = appsByTool.get(tool.name);
|
|
97
|
+
return app
|
|
98
|
+
? {
|
|
99
|
+
...tool,
|
|
100
|
+
_meta: { ...tool._meta, ui: app.toolMeta },
|
|
101
|
+
}
|
|
102
|
+
: { ...tool };
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function escapeHtml(value) {
|
|
106
|
+
return value
|
|
107
|
+
.replaceAll("&", "&")
|
|
108
|
+
.replaceAll("<", "<")
|
|
109
|
+
.replaceAll(">", ">")
|
|
110
|
+
.replaceAll('"', """)
|
|
111
|
+
.replaceAll("'", "'");
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Render a self-contained, sandbox-compatible MCP App document.
|
|
115
|
+
*
|
|
116
|
+
* The view keeps no durable state and exposes no mutation control. It receives
|
|
117
|
+
* the authoritative tool input/result from the host, bounds large rendering,
|
|
118
|
+
* and presents the text fallback when structured content is unavailable.
|
|
119
|
+
*/
|
|
120
|
+
export function renderPmMcpAppHtml(contract) {
|
|
121
|
+
const title = escapeHtml(contract.name);
|
|
122
|
+
const description = escapeHtml(contract.description);
|
|
123
|
+
const appInfo = JSON.stringify({
|
|
124
|
+
name: `pm-${contract.id}-view`,
|
|
125
|
+
version: PM_MCP_APPS_SPEC_VERSION,
|
|
126
|
+
});
|
|
127
|
+
const protocolVersion = JSON.stringify(PM_MCP_APPS_SPEC_VERSION);
|
|
128
|
+
return `<!doctype html>
|
|
129
|
+
<html lang="en">
|
|
130
|
+
<head>
|
|
131
|
+
<meta charset="utf-8">
|
|
132
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
133
|
+
<title>${title}</title>
|
|
134
|
+
<style>
|
|
135
|
+
:root{color-scheme:light dark;--ink:#172554;--muted:#526078;--panel:#f8fafc;--line:#cbd5e1;--signal:#0f766e;--accent:#4338ca;--danger:#b91c1c;font-family:Inter,ui-sans-serif,system-ui,sans-serif}
|
|
136
|
+
@media(prefers-color-scheme:dark){:root{--ink:#e0e7ff;--muted:#a8b3c7;--panel:#111827;--line:#334155;--signal:#5eead4;--accent:#a5b4fc;--danger:#fca5a5}}
|
|
137
|
+
*{box-sizing:border-box}body{margin:0;background:var(--panel);color:var(--ink)}main{display:grid;gap:1rem;padding:clamp(.9rem,3vw,1.5rem);max-width:76rem;margin:auto}header{display:grid;gap:.35rem;border-bottom:1px solid var(--line);padding-bottom:.8rem}h1{font-size:clamp(1.2rem,3vw,1.75rem);line-height:1.1;margin:0;letter-spacing:-.02em}p{margin:0;color:var(--muted);line-height:1.5}.status{display:flex;align-items:center;gap:.5rem;font:600 .75rem ui-monospace,monospace;text-transform:uppercase;letter-spacing:.06em}.status::before{content:"";width:.55rem;height:.55rem;border-radius:50%;background:var(--signal)}section{border:1px solid var(--line);border-radius:.8rem;padding:1rem;background:color-mix(in srgb,var(--panel) 92%,var(--accent) 8%)}h2{font-size:.75rem;text-transform:uppercase;letter-spacing:.08em;margin:0 0 .7rem;color:var(--accent)}pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:34rem;overflow:auto;margin:0;font:500 .78rem/1.55 ui-monospace,SFMono-Regular,monospace;tab-size:2}button{justify-self:start;border:1px solid var(--accent);border-radius:.45rem;background:transparent;color:var(--accent);padding:.55rem .75rem;font:600 .78rem inherit;cursor:pointer}button:focus-visible{outline:3px solid var(--signal);outline-offset:2px}.notice{color:var(--danger)}@media(max-width:40rem){main{padding:.75rem}section{padding:.8rem}pre{max-height:24rem}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}
|
|
138
|
+
</style>
|
|
139
|
+
</head>
|
|
140
|
+
<body>
|
|
141
|
+
<main>
|
|
142
|
+
<header><div class="status" id="status" role="status" aria-live="polite">Connecting to host</div><h1>${title}</h1><p>${description}</p></header>
|
|
143
|
+
<section aria-labelledby="summary-title"><h2 id="summary-title">Authoritative result</h2><pre id="result" tabindex="0">Waiting for the host tool result…</pre></section>
|
|
144
|
+
<section aria-labelledby="input-title"><h2 id="input-title">Invocation context</h2><pre id="input" tabindex="0">No tool input received.</pre></section>
|
|
145
|
+
<button type="button" id="copy">Copy visible evidence</button>
|
|
146
|
+
</main>
|
|
147
|
+
<script>
|
|
148
|
+
(()=>{"use strict";const MAX=24000,status=document.querySelector("#status"),result=document.querySelector("#result"),input=document.querySelector("#input"),pending=new Map();let nextId=1;const render=(node,value)=>{let text;try{text=typeof value==="string"?value:JSON.stringify(value,null,2)}catch{text="Result could not be serialized."}if(text.length>MAX)text=text.slice(0,MAX)+"\\n\\n[View truncated at "+MAX+" characters; use the authoritative pm tool with a cursor or narrower projection.]";node.textContent=text};const send=(message)=>window.parent.postMessage(message,"*");window.addEventListener("message",event=>{if(event.source!==window.parent||!event.data||event.data.jsonrpc!=="2.0")return;const message=event.data;if(message.id!==undefined&&pending.has(message.id)){pending.get(message.id)(message);pending.delete(message.id);return}if(message.method==="ui/notifications/tool-input"||message.method==="ui/notifications/tool-input-partial"){render(input,message.params?.arguments??message.params);status.textContent="Input received"}else if(message.method==="ui/notifications/tool-result"){render(result,message.params);status.textContent="Current tool result"}else if(message.method==="ui/notifications/tool-cancelled"){status.textContent="Tool call cancelled";status.classList.add("notice")}else if(message.method==="ui/notifications/host-context-changed"&&message.params?.theme){document.documentElement.style.colorScheme=message.params.theme}});const request=(method,params)=>new Promise(resolve=>{const id=nextId++;pending.set(id,resolve);send({jsonrpc:"2.0",id,method,params})});document.querySelector("#copy").addEventListener("click",async()=>{const text=result.textContent+"\\n\\n"+input.textContent;try{await navigator.clipboard.writeText(text);status.textContent="Visible evidence copied"}catch{status.textContent="Clipboard permission unavailable";status.classList.add("notice")}});request("ui/initialize",{appInfo:${appInfo},appCapabilities:{},protocolVersion:${protocolVersion}}).then(message=>{if(message.error){status.textContent="Host rejected MCP App initialization";status.classList.add("notice");return}send({jsonrpc:"2.0",method:"ui/notifications/initialized"});status.textContent="Connected — awaiting authoritative result"})})();
|
|
149
|
+
</script>
|
|
150
|
+
</body>
|
|
151
|
+
</html>`;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=apps.js.map
|
|
154
|
+
//# debugId=e6c49c89-781e-59a3-9c19-6a1c40424587
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { PmMcpHttpHeaders } from "./transport.js";
|
|
2
|
+
/** Authorization failure with an HTTP status and disclosure-safe context. */
|
|
3
|
+
export declare class PmMcpAuthorizationError extends Error {
|
|
4
|
+
/** HTTP status required at the remote MCP boundary. */
|
|
5
|
+
readonly httpStatus: 401 | 403;
|
|
6
|
+
/** Optional RFC 6750 challenge safe to send to an unauthenticated client. */
|
|
7
|
+
readonly challenge?: string;
|
|
8
|
+
/** Create one remote authorization refusal. */
|
|
9
|
+
constructor(message: string, httpStatus: 401 | 403, challenge?: string);
|
|
10
|
+
}
|
|
11
|
+
/** RFC 9728 metadata served by a protected pm MCP resource. */
|
|
12
|
+
export interface PmMcpProtectedResourceMetadata {
|
|
13
|
+
/** Canonical MCP resource URI used for token audience binding. */
|
|
14
|
+
resource: string;
|
|
15
|
+
/** Independent authorization-server issuers accepted by this resource. */
|
|
16
|
+
authorization_servers: string[];
|
|
17
|
+
/** Minimal scopes used for initial least-privilege authorization. */
|
|
18
|
+
scopes_supported?: string[];
|
|
19
|
+
}
|
|
20
|
+
/** Validated authorization-server discovery fields needed by MCP clients. */
|
|
21
|
+
export interface PmMcpAuthorizationServerMetadata {
|
|
22
|
+
/** Exact issuer identifier. */
|
|
23
|
+
issuer: string;
|
|
24
|
+
/** Authorization endpoint for code flows. */
|
|
25
|
+
authorization_endpoint?: string;
|
|
26
|
+
/** Token endpoint used to redeem authorization codes. */
|
|
27
|
+
token_endpoint?: string;
|
|
28
|
+
/** PKCE methods advertised by the authorization server. */
|
|
29
|
+
code_challenge_methods_supported: string[];
|
|
30
|
+
/** Whether URL-form Client ID Metadata Documents are supported. */
|
|
31
|
+
client_id_metadata_document_supported?: boolean;
|
|
32
|
+
/** Deprecated dynamic-registration fallback endpoint. */
|
|
33
|
+
registration_endpoint?: string;
|
|
34
|
+
}
|
|
35
|
+
/** Discovery metadata after endpoint and PKCE validation succeeds. */
|
|
36
|
+
export interface PmMcpValidatedAuthorizationServerMetadata extends PmMcpAuthorizationServerMetadata {
|
|
37
|
+
/** Validated HTTPS authorization endpoint for code flows. */
|
|
38
|
+
authorization_endpoint: string;
|
|
39
|
+
/** Validated HTTPS token endpoint used to redeem authorization codes. */
|
|
40
|
+
token_endpoint: string;
|
|
41
|
+
}
|
|
42
|
+
/** Client registration strategy ordered by current MCP preference. */
|
|
43
|
+
export type PmMcpClientRegistrationMode = "pre_registered" | "client_id_metadata_document" | "dynamic" | "user_supplied";
|
|
44
|
+
/** Bound access-token facts returned by a host-provided verifier. */
|
|
45
|
+
export interface PmMcpAccessTokenClaims {
|
|
46
|
+
/** Stable authenticated principal without raw token material. */
|
|
47
|
+
principal: string;
|
|
48
|
+
/** Issuer that minted the token. */
|
|
49
|
+
issuer: string;
|
|
50
|
+
/** Intended resource audiences. */
|
|
51
|
+
audience: string | string[];
|
|
52
|
+
/** Granted OAuth scopes. */
|
|
53
|
+
scopes: string[];
|
|
54
|
+
}
|
|
55
|
+
/** Policy a Streamable HTTP adapter enforces before dispatching MCP. */
|
|
56
|
+
export interface PmMcpHttpAuthorizationPolicy {
|
|
57
|
+
/** Exact accepted issuer. */
|
|
58
|
+
issuer: string;
|
|
59
|
+
/** Exact canonical MCP resource audience. */
|
|
60
|
+
resource: string;
|
|
61
|
+
/** Scopes required for this endpoint or operation. */
|
|
62
|
+
requiredScopes?: string[];
|
|
63
|
+
/** Protected-resource metadata location for RFC 6750 challenges. */
|
|
64
|
+
resourceMetadataUrl: string;
|
|
65
|
+
/** Validate an opaque or structured access token without passing it onward. */
|
|
66
|
+
verifyAccessToken: (token: string) => PmMcpAccessTokenClaims | Promise<PmMcpAccessTokenClaims>;
|
|
67
|
+
}
|
|
68
|
+
/** W3C trace context accepted from request `_meta`. */
|
|
69
|
+
export interface PmMcpTraceContext {
|
|
70
|
+
/** W3C trace-parent value. */
|
|
71
|
+
traceparent?: string;
|
|
72
|
+
/** W3C trace-state value. */
|
|
73
|
+
tracestate?: string;
|
|
74
|
+
/** Allowlisted W3C baggage members only. */
|
|
75
|
+
baggage?: string;
|
|
76
|
+
}
|
|
77
|
+
/** Build and validate protected-resource metadata for a remote pm endpoint. */
|
|
78
|
+
export declare function buildMcpProtectedResourceMetadata(input: {
|
|
79
|
+
resource: string;
|
|
80
|
+
authorizationServers: readonly string[];
|
|
81
|
+
scopes?: readonly string[];
|
|
82
|
+
}): PmMcpProtectedResourceMetadata;
|
|
83
|
+
/** Construct OAuth and OIDC discovery URLs in the MCP-required order. */
|
|
84
|
+
export declare function buildMcpAuthorizationDiscoveryUrls(issuer: string): string[];
|
|
85
|
+
/** Validate authorization-server metadata, exact issuer binding, and S256 PKCE. */
|
|
86
|
+
export declare function validateMcpAuthorizationServerMetadata(value: unknown, expectedIssuer: string): PmMcpValidatedAuthorizationServerMetadata;
|
|
87
|
+
/** Apply the current pre-registration, metadata-document, dynamic, prompt order. */
|
|
88
|
+
export declare function selectMcpClientRegistrationMode(input: {
|
|
89
|
+
hasPreRegisteredClient: boolean;
|
|
90
|
+
metadata: Pick<PmMcpAuthorizationServerMetadata, "client_id_metadata_document_supported" | "registration_endpoint">;
|
|
91
|
+
}): PmMcpClientRegistrationMode;
|
|
92
|
+
/** Validate a present authorization-response issuer before code redemption. */
|
|
93
|
+
export declare function validateMcpAuthorizationResponseIssuer(input: {
|
|
94
|
+
expectedIssuer: string;
|
|
95
|
+
responseIssuer?: string;
|
|
96
|
+
issuerParameterSupported?: boolean;
|
|
97
|
+
}): void;
|
|
98
|
+
/** Validate a self-hosted Client ID Metadata Document and exact redirect set. */
|
|
99
|
+
export declare function validateMcpClientMetadataDocument(value: unknown, documentUrl: string): Record<string, unknown>;
|
|
100
|
+
/** Build bounded dynamic-registration metadata for explicit legacy fallback. */
|
|
101
|
+
export declare function buildMcpDynamicRegistrationMetadata(input: {
|
|
102
|
+
redirectUris: readonly string[];
|
|
103
|
+
applicationType: "native" | "web";
|
|
104
|
+
clientName: string;
|
|
105
|
+
}): Record<string, unknown>;
|
|
106
|
+
/** In-memory issuer-keyed credential primitive that never reuses cross-issuer state. */
|
|
107
|
+
export declare class PmMcpIssuerCredentialStore<Credential extends Record<string, unknown>> {
|
|
108
|
+
#private;
|
|
109
|
+
/** Persist a cloned credential under the exact validated issuer. */
|
|
110
|
+
set(issuer: string, credential: Credential): void;
|
|
111
|
+
/** Read a cloned credential only for the exact issuer. */
|
|
112
|
+
get(issuer: string): Credential | undefined;
|
|
113
|
+
/** Remove credentials for one issuer during revocation or re-registration. */
|
|
114
|
+
delete(issuer: string): boolean;
|
|
115
|
+
}
|
|
116
|
+
/** Extract W3C trace context with strict syntax, size, and baggage allowlists. */
|
|
117
|
+
export declare function extractMcpTraceContext(params: unknown, options?: {
|
|
118
|
+
baggageAllowlist?: readonly string[];
|
|
119
|
+
}): PmMcpTraceContext;
|
|
120
|
+
/** Run one request with trace context isolated from every concurrent request. */
|
|
121
|
+
export declare function runWithMcpTraceContext<Result>(context: PmMcpTraceContext, callback: () => Result): Result;
|
|
122
|
+
/** Read a defensive copy of the current request's trace context. */
|
|
123
|
+
export declare function getActiveMcpTraceContext(): PmMcpTraceContext | undefined;
|
|
124
|
+
/** Enforce bearer location, issuer, audience, and least-privilege scopes. */
|
|
125
|
+
export declare function authorizeMcpHttpRequest(input: {
|
|
126
|
+
headers: PmMcpHttpHeaders;
|
|
127
|
+
requestUrl: string;
|
|
128
|
+
policy: PmMcpHttpAuthorizationPolicy;
|
|
129
|
+
}): Promise<PmMcpAccessTokenClaims>;
|
|
130
|
+
/** Create an exact opaque-token verifier without exposing token values in results. */
|
|
131
|
+
export declare function createMcpStaticBearerVerifier(input: {
|
|
132
|
+
token: string;
|
|
133
|
+
claims: PmMcpAccessTokenClaims;
|
|
134
|
+
}): (token: string) => PmMcpAccessTokenClaims;
|