@mwturnbull/papi-mcp 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +320 -0
  3. package/dist/config/assembler.d.ts +6 -0
  4. package/dist/config/assembler.d.ts.map +1 -0
  5. package/dist/config/assembler.js +56 -0
  6. package/dist/config/assembler.js.map +1 -0
  7. package/dist/config/parser.d.ts +6 -0
  8. package/dist/config/parser.d.ts.map +1 -0
  9. package/dist/config/parser.js +79 -0
  10. package/dist/config/parser.js.map +1 -0
  11. package/dist/config/snippets.d.ts +12 -0
  12. package/dist/config/snippets.d.ts.map +1 -0
  13. package/dist/config/snippets.js +75 -0
  14. package/dist/config/snippets.js.map +1 -0
  15. package/dist/git/git-ops.d.ts +16 -0
  16. package/dist/git/git-ops.d.ts.map +1 -0
  17. package/dist/git/git-ops.js +64 -0
  18. package/dist/git/git-ops.js.map +1 -0
  19. package/dist/git/github.d.ts +12 -0
  20. package/dist/git/github.d.ts.map +1 -0
  21. package/dist/git/github.js +83 -0
  22. package/dist/git/github.js.map +1 -0
  23. package/dist/git/gitlab.d.ts +11 -0
  24. package/dist/git/gitlab.d.ts.map +1 -0
  25. package/dist/git/gitlab.js +65 -0
  26. package/dist/git/gitlab.js.map +1 -0
  27. package/dist/git/provider.d.ts +33 -0
  28. package/dist/git/provider.d.ts.map +1 -0
  29. package/dist/git/provider.js +49 -0
  30. package/dist/git/provider.js.map +1 -0
  31. package/dist/papi/auth.d.ts +12 -0
  32. package/dist/papi/auth.d.ts.map +1 -0
  33. package/dist/papi/auth.js +74 -0
  34. package/dist/papi/auth.js.map +1 -0
  35. package/dist/papi/client.d.ts +19 -0
  36. package/dist/papi/client.d.ts.map +1 -0
  37. package/dist/papi/client.js +115 -0
  38. package/dist/papi/client.js.map +1 -0
  39. package/dist/papi/types.d.ts +487 -0
  40. package/dist/papi/types.d.ts.map +1 -0
  41. package/dist/papi/types.js +94 -0
  42. package/dist/papi/types.js.map +1 -0
  43. package/dist/redaction/redactor.d.ts +25 -0
  44. package/dist/redaction/redactor.d.ts.map +1 -0
  45. package/dist/redaction/redactor.js +128 -0
  46. package/dist/redaction/redactor.js.map +1 -0
  47. package/dist/server.d.ts +3 -0
  48. package/dist/server.d.ts.map +1 -0
  49. package/dist/server.js +219 -0
  50. package/dist/server.js.map +1 -0
  51. package/dist/tools/activate.d.ts +16 -0
  52. package/dist/tools/activate.d.ts.map +1 -0
  53. package/dist/tools/activate.js +59 -0
  54. package/dist/tools/activate.js.map +1 -0
  55. package/dist/tools/diff-configs.d.ts +3 -0
  56. package/dist/tools/diff-configs.d.ts.map +1 -0
  57. package/dist/tools/diff-configs.js +152 -0
  58. package/dist/tools/diff-configs.js.map +1 -0
  59. package/dist/tools/get-property-config.d.ts +9 -0
  60. package/dist/tools/get-property-config.d.ts.map +1 -0
  61. package/dist/tools/get-property-config.js +53 -0
  62. package/dist/tools/get-property-config.js.map +1 -0
  63. package/dist/tools/pipeline.d.ts +11 -0
  64. package/dist/tools/pipeline.d.ts.map +1 -0
  65. package/dist/tools/pipeline.js +9 -0
  66. package/dist/tools/pipeline.js.map +1 -0
  67. package/dist/tools/sync-property.d.ts +9 -0
  68. package/dist/tools/sync-property.d.ts.map +1 -0
  69. package/dist/tools/sync-property.js +65 -0
  70. package/dist/tools/sync-property.js.map +1 -0
  71. package/dist/tools/write-snippet.d.ts +30 -0
  72. package/dist/tools/write-snippet.d.ts.map +1 -0
  73. package/dist/tools/write-snippet.js +92 -0
  74. package/dist/tools/write-snippet.js.map +1 -0
  75. package/dist/validation/local.d.ts +3 -0
  76. package/dist/validation/local.d.ts.map +1 -0
  77. package/dist/validation/local.js +290 -0
  78. package/dist/validation/local.js.map +1 -0
  79. package/dist/validation/papi.d.ts +6 -0
  80. package/dist/validation/papi.d.ts.map +1 -0
  81. package/dist/validation/papi.js +59 -0
  82. package/dist/validation/papi.js.map +1 -0
  83. package/package.json +55 -0
  84. package/src/skill/system-prompt.md +205 -0
  85. package/templates/.gitkeep +0 -0
  86. package/templates/CLAUDE.md +115 -0
  87. package/templates/copilot-instructions.md +78 -0
@@ -0,0 +1,64 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const execFileAsync = promisify(execFile);
4
+ export class GitError extends Error {
5
+ exitCode;
6
+ constructor(message, exitCode) {
7
+ super(message);
8
+ this.exitCode = exitCode;
9
+ this.name = 'GitError';
10
+ }
11
+ }
12
+ export async function createBranch(repoPath, branchName) {
13
+ await git(repoPath, ['checkout', '-b', branchName]);
14
+ }
15
+ export async function commitAndPush(repoPath, message, files) {
16
+ if (files && files.length > 0) {
17
+ await git(repoPath, ['add', ...files]);
18
+ }
19
+ else {
20
+ await git(repoPath, ['add', '-A']);
21
+ }
22
+ await git(repoPath, ['commit', '-m', message]);
23
+ const branch = await getCurrentBranch(repoPath);
24
+ await git(repoPath, ['push', '-u', 'origin', branch]);
25
+ }
26
+ export async function getCurrentBranch(repoPath) {
27
+ const { stdout } = await git(repoPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
28
+ return stdout.trim();
29
+ }
30
+ export async function getRemoteUrl(repoPath) {
31
+ const { stdout } = await git(repoPath, ['remote', 'get-url', 'origin']);
32
+ return stdout.trim();
33
+ }
34
+ export function parseRemoteUrl(url) {
35
+ // SSH format: git@github.com:owner/repo.git
36
+ const sshMatch = url.match(/^git@([^:]+):([^/]+)\/(.+?)(?:\.git)?$/);
37
+ if (sshMatch) {
38
+ return { host: sshMatch[1], owner: sshMatch[2], repo: sshMatch[3] };
39
+ }
40
+ // HTTPS format: https://github.com/owner/repo.git
41
+ const httpsMatch = url.match(/^https?:\/\/([^/]+)\/([^/]+)\/(.+?)(?:\.git)?$/);
42
+ if (httpsMatch) {
43
+ return { host: httpsMatch[1], owner: httpsMatch[2], repo: httpsMatch[3] };
44
+ }
45
+ throw new GitError(`Cannot parse remote URL: ${url}. Expected SSH (git@host:owner/repo) or HTTPS format.`);
46
+ }
47
+ export function buildBranchName(type, description) {
48
+ const sanitized = description
49
+ .toLowerCase()
50
+ .replace(/[^a-z0-9-]/g, '-')
51
+ .replace(/-+/g, '-')
52
+ .replace(/^-|-$/g, '');
53
+ return `akamai/${type}/${sanitized}`;
54
+ }
55
+ async function git(cwd, args) {
56
+ try {
57
+ return await execFileAsync('git', args, { cwd });
58
+ }
59
+ catch (error) {
60
+ const err = error;
61
+ throw new GitError(`git ${args[0]} failed: ${err.stderr ?? 'Unknown error'}`, err.code);
62
+ }
63
+ }
64
+ //# sourceMappingURL=git-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-ops.js","sourceRoot":"","sources":["../../src/git/git-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { GitProvider, MergeRequestParams, MergeRequestResult, PipelineTriggerParams, PipelineTriggerResult } from './provider.js';
2
+ export declare class GitHubClient implements GitProvider {
3
+ private readonly host;
4
+ private readonly owner;
5
+ private readonly repo;
6
+ private readonly token;
7
+ constructor(host: string, owner: string, repo: string);
8
+ createMergeRequest(params: MergeRequestParams): Promise<MergeRequestResult>;
9
+ triggerPipeline(params: PipelineTriggerParams): Promise<PipelineTriggerResult>;
10
+ private resolveToken;
11
+ }
12
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/git/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvI,qBAAa,YAAa,YAAW,WAAW;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAO/C,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA4B3E,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+CpF,OAAO,CAAC,YAAY;CAQrB"}
@@ -0,0 +1,83 @@
1
+ export class GitHubClient {
2
+ host;
3
+ owner;
4
+ repo;
5
+ token;
6
+ constructor(host, owner, repo) {
7
+ this.host = host;
8
+ this.owner = owner;
9
+ this.repo = repo;
10
+ this.token = this.resolveToken();
11
+ }
12
+ async createMergeRequest(params) {
13
+ const apiBase = this.host === 'github.com' ? 'https://api.github.com' : `https://${this.host}/api/v3`;
14
+ const url = `${apiBase}/repos/${this.owner}/${this.repo}/pulls`;
15
+ const response = await fetch(url, {
16
+ method: 'POST',
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ 'Authorization': `Bearer ${this.token}`,
20
+ 'Accept': 'application/vnd.github+json',
21
+ },
22
+ body: JSON.stringify({
23
+ head: params.sourceBranch,
24
+ base: params.targetBranch,
25
+ title: params.title,
26
+ body: params.description,
27
+ }),
28
+ });
29
+ if (!response.ok) {
30
+ const body = await response.text();
31
+ throw new Error(`GitHub PR creation failed (${response.status}): ${body}`);
32
+ }
33
+ const data = await response.json();
34
+ return { url: data.html_url, id: data.number, provider: 'github' };
35
+ }
36
+ async triggerPipeline(params) {
37
+ const apiBase = this.host === 'github.com' ? 'https://api.github.com' : `https://${this.host}/api/v3`;
38
+ // List workflows to find the first one
39
+ const listUrl = `${apiBase}/repos/${this.owner}/${this.repo}/actions/workflows`;
40
+ const listResponse = await fetch(listUrl, {
41
+ headers: {
42
+ 'Authorization': `Bearer ${this.token}`,
43
+ 'Accept': 'application/vnd.github+json',
44
+ },
45
+ });
46
+ if (!listResponse.ok) {
47
+ throw new Error(`Failed to list GitHub workflows (${listResponse.status})`);
48
+ }
49
+ const workflows = await listResponse.json();
50
+ const workflow = workflows.workflows[0];
51
+ if (!workflow) {
52
+ throw new Error('No GitHub Actions workflows found in repository');
53
+ }
54
+ const dispatchUrl = `${apiBase}/repos/${this.owner}/${this.repo}/actions/workflows/${workflow.id}/dispatches`;
55
+ const response = await fetch(dispatchUrl, {
56
+ method: 'POST',
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ 'Authorization': `Bearer ${this.token}`,
60
+ 'Accept': 'application/vnd.github+json',
61
+ },
62
+ body: JSON.stringify({
63
+ ref: params.branch,
64
+ inputs: params.variables ?? {},
65
+ }),
66
+ });
67
+ if (!response.ok) {
68
+ const body = await response.text();
69
+ throw new Error(`GitHub workflow dispatch failed (${response.status}): ${body}`);
70
+ }
71
+ // GitHub dispatch returns 204 No Content on success, no body
72
+ const workflowUrl = `https://${this.host}/${this.owner}/${this.repo}/actions`;
73
+ return { url: workflowUrl, id: workflow.id, provider: 'github' };
74
+ }
75
+ resolveToken() {
76
+ const token = process.env['GITHUB_TOKEN'] ?? process.env['GH_TOKEN'];
77
+ if (!token) {
78
+ throw new Error('GitHub token not found. Set one of: GITHUB_TOKEN, GH_TOKEN');
79
+ }
80
+ return token;
81
+ }
82
+ }
83
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/git/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { GitProvider, MergeRequestParams, MergeRequestResult, PipelineTriggerParams, PipelineTriggerResult } from './provider.js';
2
+ export declare class GitLabClient implements GitProvider {
3
+ private readonly host;
4
+ private readonly projectPath;
5
+ private readonly token;
6
+ constructor(host: string, owner: string, repo: string);
7
+ createMergeRequest(params: MergeRequestParams): Promise<MergeRequestResult>;
8
+ triggerPipeline(params: PipelineTriggerParams): Promise<PipelineTriggerResult>;
9
+ private resolveToken;
10
+ }
11
+ //# sourceMappingURL=gitlab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab.d.ts","sourceRoot":"","sources":["../../src/git/gitlab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvI,qBAAa,YAAa,YAAW,WAAW;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAM/C,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyB3E,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA2BpF,OAAO,CAAC,YAAY;CAYrB"}
@@ -0,0 +1,65 @@
1
+ export class GitLabClient {
2
+ host;
3
+ projectPath;
4
+ token;
5
+ constructor(host, owner, repo) {
6
+ this.host = host;
7
+ this.projectPath = encodeURIComponent(`${owner}/${repo}`);
8
+ this.token = this.resolveToken();
9
+ }
10
+ async createMergeRequest(params) {
11
+ const url = `https://${this.host}/api/v4/projects/${this.projectPath}/merge_requests`;
12
+ const response = await fetch(url, {
13
+ method: 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ 'PRIVATE-TOKEN': this.token,
17
+ },
18
+ body: JSON.stringify({
19
+ source_branch: params.sourceBranch,
20
+ target_branch: params.targetBranch,
21
+ title: params.title,
22
+ description: params.description,
23
+ }),
24
+ });
25
+ if (!response.ok) {
26
+ const body = await response.text();
27
+ throw new Error(`GitLab MR creation failed (${response.status}): ${body}`);
28
+ }
29
+ const data = await response.json();
30
+ return { url: data.web_url, id: data.iid, provider: 'gitlab' };
31
+ }
32
+ async triggerPipeline(params) {
33
+ const url = `https://${this.host}/api/v4/projects/${this.projectPath}/pipeline`;
34
+ const variables = params.variables
35
+ ? Object.entries(params.variables).map(([key, value]) => ({ key, value, variable_type: 'env_var' }))
36
+ : [];
37
+ const response = await fetch(url, {
38
+ method: 'POST',
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ 'PRIVATE-TOKEN': this.token,
42
+ },
43
+ body: JSON.stringify({
44
+ ref: params.branch,
45
+ variables,
46
+ }),
47
+ });
48
+ if (!response.ok) {
49
+ const body = await response.text();
50
+ throw new Error(`GitLab pipeline trigger failed (${response.status}): ${body}`);
51
+ }
52
+ const data = await response.json();
53
+ return { url: data.web_url, id: data.id, provider: 'gitlab' };
54
+ }
55
+ resolveToken() {
56
+ const token = process.env['GITLAB_TOKEN']
57
+ ?? process.env['GITLAB_PERSONAL_ACCESS_TOKEN']
58
+ ?? process.env['CI_JOB_TOKEN'];
59
+ if (!token) {
60
+ throw new Error('GitLab token not found. Set one of: GITLAB_TOKEN, GITLAB_PERSONAL_ACCESS_TOKEN, CI_JOB_TOKEN');
61
+ }
62
+ return token;
63
+ }
64
+ }
65
+ //# sourceMappingURL=gitlab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/git/gitlab.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export interface MergeRequestParams {
2
+ title: string;
3
+ description: string;
4
+ sourceBranch: string;
5
+ targetBranch: string;
6
+ }
7
+ export interface MergeRequestResult {
8
+ url: string;
9
+ id: number | string;
10
+ provider: 'gitlab' | 'github';
11
+ }
12
+ export interface PipelineTriggerParams {
13
+ branch: string;
14
+ variables?: Record<string, string>;
15
+ }
16
+ export interface PipelineTriggerResult {
17
+ url: string;
18
+ id: number | string;
19
+ provider: 'gitlab' | 'github';
20
+ }
21
+ export interface GitProvider {
22
+ createMergeRequest(params: MergeRequestParams): Promise<MergeRequestResult>;
23
+ triggerPipeline(params: PipelineTriggerParams): Promise<PipelineTriggerResult>;
24
+ }
25
+ export type ProviderType = 'gitlab' | 'github';
26
+ export declare function detectProvider(repoPath: string): Promise<{
27
+ type: ProviderType;
28
+ host: string;
29
+ owner: string;
30
+ repo: string;
31
+ }>;
32
+ export declare function createProvider(repoPath: string): Promise<GitProvider>;
33
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/git/provider.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC5E,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAChF;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAU/C,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BjI;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAU3E"}
@@ -0,0 +1,49 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { getRemoteUrl, parseRemoteUrl } from './git-ops.js';
4
+ export async function detectProvider(repoPath) {
5
+ // Check .papi-mcp.json config first
6
+ const config = await loadGitProviderConfig(repoPath);
7
+ if (config?.gitProvider?.type) {
8
+ const remoteUrl = await getRemoteUrl(repoPath);
9
+ const remote = parseRemoteUrl(remoteUrl);
10
+ return {
11
+ type: config.gitProvider.type,
12
+ host: config.gitProvider.host ?? remote.host,
13
+ owner: remote.owner,
14
+ repo: remote.repo,
15
+ };
16
+ }
17
+ // Auto-detect from remote URL
18
+ const remoteUrl = await getRemoteUrl(repoPath);
19
+ const remote = parseRemoteUrl(remoteUrl);
20
+ if (remote.host.includes('gitlab')) {
21
+ return { type: 'gitlab', ...remote };
22
+ }
23
+ if (remote.host.includes('github')) {
24
+ return { type: 'github', ...remote };
25
+ }
26
+ throw new Error(`Cannot auto-detect git provider from host "${remote.host}". ` +
27
+ `Configure .papi-mcp.json with:\n` +
28
+ `{\n "gitProvider": {\n "type": "gitlab" | "github",\n "host": "${remote.host}"\n }\n}`);
29
+ }
30
+ export async function createProvider(repoPath) {
31
+ const info = await detectProvider(repoPath);
32
+ if (info.type === 'gitlab') {
33
+ const { GitLabClient } = await import('./gitlab.js');
34
+ return new GitLabClient(info.host, info.owner, info.repo);
35
+ }
36
+ const { GitHubClient } = await import('./github.js');
37
+ return new GitHubClient(info.host, info.owner, info.repo);
38
+ }
39
+ async function loadGitProviderConfig(repoPath) {
40
+ try {
41
+ const configPath = resolve(repoPath, '.papi-mcp.json');
42
+ const content = await readFile(configPath, 'utf-8');
43
+ return JSON.parse(content);
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/git/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAyC5D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,oCAAoC;IACpC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;YAC7B,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI;YAC5C,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,8CAA8C,MAAM,CAAC,IAAI,KAAK;QAC9D,kCAAkC;QAClC,yEAAyE,MAAM,CAAC,IAAI,WAAW,CAChG,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACrD,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACrD,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IACnD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAkB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { EdgeGridCredentials } from './types.js';
2
+ export declare class AuthError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ interface ResolveOptions {
6
+ edgercPath?: string;
7
+ section?: string;
8
+ }
9
+ export declare function resolveCredentials(options?: ResolveOptions): Promise<EdgeGridCredentials>;
10
+ export declare function parseEdgerc(content: string, section: string): EdgeGridCredentials;
11
+ export {};
12
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/papi/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2BnG;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CA2CjF"}
@@ -0,0 +1,74 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export class AuthError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'AuthError';
8
+ }
9
+ }
10
+ export async function resolveCredentials(options = {}) {
11
+ const section = options.section ?? 'default';
12
+ // Try .edgerc file first
13
+ const edgercPath = options.edgercPath ?? resolve(homedir(), '.edgerc');
14
+ try {
15
+ const content = await readFile(edgercPath, 'utf-8');
16
+ return parseEdgerc(content, section);
17
+ }
18
+ catch {
19
+ // File not found or unreadable, try env vars
20
+ }
21
+ // Try environment variables
22
+ const clientSecret = process.env['AKAMAI_CLIENT_SECRET'];
23
+ const host = process.env['AKAMAI_HOST'];
24
+ const accessToken = process.env['AKAMAI_ACCESS_TOKEN'];
25
+ const clientToken = process.env['AKAMAI_CLIENT_TOKEN'];
26
+ if (clientSecret && host && accessToken && clientToken) {
27
+ return { clientSecret, host, accessToken, clientToken };
28
+ }
29
+ throw new AuthError(`Could not resolve Akamai credentials. Provide either:\n` +
30
+ ` 1. An .edgerc file at ${edgercPath} (section: [${section}])\n` +
31
+ ` 2. Environment variables: AKAMAI_CLIENT_SECRET, AKAMAI_HOST, AKAMAI_ACCESS_TOKEN, AKAMAI_CLIENT_TOKEN`);
32
+ }
33
+ export function parseEdgerc(content, section) {
34
+ const lines = content.split('\n');
35
+ let inSection = false;
36
+ const values = {};
37
+ for (const line of lines) {
38
+ const trimmed = line.trim();
39
+ // Section header
40
+ const sectionMatch = trimmed.match(/^\[(.+)]$/);
41
+ if (sectionMatch) {
42
+ inSection = sectionMatch[1] === section;
43
+ continue;
44
+ }
45
+ if (!inSection)
46
+ continue;
47
+ if (!trimmed || trimmed.startsWith('#'))
48
+ continue;
49
+ const eqIndex = trimmed.indexOf('=');
50
+ if (eqIndex === -1)
51
+ continue;
52
+ const key = trimmed.slice(0, eqIndex).trim();
53
+ const value = trimmed.slice(eqIndex + 1).trim();
54
+ values[key] = value;
55
+ }
56
+ const clientSecret = values['client_secret'];
57
+ const host = values['host']?.replace(/\/$/, '');
58
+ const accessToken = values['access_token'];
59
+ const clientToken = values['client_token'];
60
+ if (!clientSecret || !host || !accessToken || !clientToken) {
61
+ const missing = [];
62
+ if (!clientSecret)
63
+ missing.push('client_secret');
64
+ if (!host)
65
+ missing.push('host');
66
+ if (!accessToken)
67
+ missing.push('access_token');
68
+ if (!clientToken)
69
+ missing.push('client_token');
70
+ throw new AuthError(`Incomplete credentials in .edgerc section [${section}]. Missing: ${missing.join(', ')}`);
71
+ }
72
+ return { clientSecret, host, accessToken, clientToken };
73
+ }
74
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/papi/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { EdgeGridCredentials, PapiRuleTreeResponse, PapiValidationResponse, PapiVersionResponse, ActivationRequest, ActivationResponse, PapiError, PapiRule } from './types.js';
2
+ export declare class PapiClientError extends Error {
3
+ readonly statusCode: number;
4
+ readonly papiError?: PapiError | undefined;
5
+ constructor(message: string, statusCode: number, papiError?: PapiError | undefined);
6
+ }
7
+ export declare class PapiClient {
8
+ private readonly credentials;
9
+ constructor(credentials: EdgeGridCredentials);
10
+ getRuleTree(propertyId: string, version?: number): Promise<PapiRuleTreeResponse>;
11
+ validateRuleTree(propertyId: string, version: number, ruleTree: PapiRule): Promise<PapiValidationResponse>;
12
+ getPropertyVersions(propertyId: string): Promise<PapiVersionResponse[]>;
13
+ getPropertyVersion(propertyId: string, version: number): Promise<PapiVersionResponse>;
14
+ activateProperty(request: ActivationRequest): Promise<ActivationResponse>;
15
+ getActivationStatus(propertyId: string, activationId: string): Promise<ActivationResponse>;
16
+ private getLatestVersion;
17
+ private request;
18
+ }
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/papi/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,UAAU,EAAE,MAAM;aAClB,SAAS,CAAC,EAAE,SAAS;gBAFrC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,SAAS,YAAA;CAKxC;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;gBAEtC,WAAW,EAAE,mBAAmB;IAItC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMhF,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAO1G,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAMvE,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQrF,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAczE,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAKlF,gBAAgB;YAQhB,OAAO;CA2DtB"}
@@ -0,0 +1,115 @@
1
+ import EdgeGrid from 'akamai-edgegrid';
2
+ export class PapiClientError extends Error {
3
+ statusCode;
4
+ papiError;
5
+ constructor(message, statusCode, papiError) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.papiError = papiError;
9
+ this.name = 'PapiClientError';
10
+ }
11
+ }
12
+ export class PapiClient {
13
+ credentials;
14
+ constructor(credentials) {
15
+ this.credentials = credentials;
16
+ }
17
+ async getRuleTree(propertyId, version) {
18
+ const ver = version ?? (await this.getLatestVersion(propertyId));
19
+ const path = `/papi/v1/properties/${propertyId}/versions/${ver}/rules`;
20
+ return this.request('GET', path);
21
+ }
22
+ async validateRuleTree(propertyId, version, ruleTree) {
23
+ // Fetch current rule tree to get its etag for optimistic concurrency
24
+ const current = await this.getRuleTree(propertyId, version);
25
+ const path = `/papi/v1/properties/${propertyId}/versions/${version}/rules?validateRules=true&validateMode=full`;
26
+ return this.request('PUT', path, { rules: ruleTree }, { 'If-Match': current.etag });
27
+ }
28
+ async getPropertyVersions(propertyId) {
29
+ const path = `/papi/v1/properties/${propertyId}/versions`;
30
+ const response = await this.request('GET', path);
31
+ return response.versions.items;
32
+ }
33
+ async getPropertyVersion(propertyId, version) {
34
+ const path = `/papi/v1/properties/${propertyId}/versions/${version}`;
35
+ const response = await this.request('GET', path);
36
+ const item = response.versions.items[0];
37
+ if (!item)
38
+ throw new PapiClientError(`Version ${version} not found`, 404);
39
+ return item;
40
+ }
41
+ async activateProperty(request) {
42
+ const path = `/papi/v1/properties/${request.propertyId}/activations`;
43
+ const body = {
44
+ propertyVersion: request.propertyVersion,
45
+ network: request.network,
46
+ note: request.note ?? 'Activated via papi-mcp',
47
+ notifyEmails: request.notifyEmails ?? [],
48
+ acknowledgeAllWarnings: request.acknowledgeAllWarnings ?? true,
49
+ activationType: 'ACTIVATE',
50
+ fastPush: true,
51
+ };
52
+ return this.request('POST', path, body);
53
+ }
54
+ async getActivationStatus(propertyId, activationId) {
55
+ const path = `/papi/v1/properties/${propertyId}/activations/${activationId}`;
56
+ return this.request('GET', path);
57
+ }
58
+ async getLatestVersion(propertyId) {
59
+ const versions = await this.getPropertyVersions(propertyId);
60
+ if (versions.length === 0)
61
+ throw new PapiClientError('No versions found', 404);
62
+ // Sort descending and take first
63
+ const sorted = [...versions].sort((a, b) => b.propertyVersion - a.propertyVersion);
64
+ return sorted[0].propertyVersion;
65
+ }
66
+ async request(method, path, body, additionalHeaders) {
67
+ const headers = {
68
+ 'Content-Type': 'application/json',
69
+ 'Accept': 'application/json',
70
+ ...additionalHeaders,
71
+ };
72
+ const eg = new EdgeGrid(this.credentials.clientToken, this.credentials.clientSecret, this.credentials.accessToken, this.credentials.host);
73
+ return new Promise((resolve, reject) => {
74
+ eg.auth({
75
+ path,
76
+ method,
77
+ headers,
78
+ body: body ? JSON.stringify(body) : undefined,
79
+ });
80
+ eg.send((error, _response, responseBody) => {
81
+ if (error) {
82
+ reject(new PapiClientError(`PAPI request failed: ${error.message}`, 0));
83
+ return;
84
+ }
85
+ if (!responseBody) {
86
+ reject(new PapiClientError('Empty response from PAPI', 0));
87
+ return;
88
+ }
89
+ let parsed;
90
+ try {
91
+ parsed = JSON.parse(responseBody);
92
+ }
93
+ catch {
94
+ reject(new PapiClientError('Failed to parse PAPI response', 0));
95
+ return;
96
+ }
97
+ // Check for error response
98
+ const maybeError = parsed;
99
+ if (typeof maybeError['status'] === 'number' && maybeError['status'] >= 400) {
100
+ const papiError = {
101
+ type: String(maybeError['type'] ?? ''),
102
+ title: maybeError['title'],
103
+ status: maybeError['status'],
104
+ detail: String(maybeError['detail'] ?? 'Unknown error'),
105
+ retryAfter: maybeError['retryAfter'],
106
+ };
107
+ reject(new PapiClientError(papiError.detail, papiError.status, papiError));
108
+ return;
109
+ }
110
+ resolve(parsed);
111
+ });
112
+ });
113
+ }
114
+ }
115
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/papi/client.ts"],"names":[],"mappings":"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"}