@postman/postman-plugin 0.1.2 → 0.2.0-rc.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/README.md +14 -3
- package/dist/hosts/factory.js +67 -0
- package/dist/hosts/index.js +2 -1
- package/dist/hosts/shared.js +8 -0
- package/mcp.pi.json +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -24,9 +24,9 @@ Install Postman in every compatible coding agent detected on your machine:
|
|
|
24
24
|
npx @postman/postman-plugin
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
One command configures **Claude Code, Codex, Cursor, Kimi Code,
|
|
28
|
-
Run it again to update, `status` to see what's installed,
|
|
29
|
-
uninstall; `--agent <id>` limits any of them to one agent.
|
|
27
|
+
One command configures **Claude Code, Codex, Cursor, Factory Droid, Kimi Code,
|
|
28
|
+
OpenCode and Pi**. Run it again to update, `status` to see what's installed,
|
|
29
|
+
and `remove` to uninstall; `--agent <id>` limits any of them to one agent.
|
|
30
30
|
|
|
31
31
|
You can also use the following commands to install individually:
|
|
32
32
|
|
|
@@ -54,6 +54,17 @@ claude plugin install postman@postman
|
|
|
54
54
|
codex plugin add postman@postman
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
### Factory Droid
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
droid plugin marketplace add postmanlabs/postman-plugin
|
|
61
|
+
droid plugin install postman@postman-plugin --scope user
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`droid plugin marketplace update postman-plugin`, then
|
|
65
|
+
`droid plugin update postman@postman-plugin --scope user`, updates it. Sign in
|
|
66
|
+
to Postman's MCP server with `/mcp` inside a Droid session.
|
|
67
|
+
|
|
57
68
|
### Pi
|
|
58
69
|
|
|
59
70
|
[View Postman in Pi's package gallery](https://pi.dev/packages/@postman/postman-plugin)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { GIT_URL, REPO, isSameRepo, redact } from '../source.js';
|
|
2
|
+
import { blocked, guard, mustProbeText, mustRun } from './shared.js';
|
|
3
|
+
import { result } from './types.js';
|
|
4
|
+
const MARKETPLACE = 'postman-plugin', PLUGIN_ID = `postman@${MARKETPLACE}`, SCOPE = 'user', NEXT = 'Restart Droid for the change to take effect.';
|
|
5
|
+
function hasInstalledPlugin(text) {
|
|
6
|
+
return text.split('\n').some((line) => new RegExp(`^${PLUGIN_ID}\\s+\\[${SCOPE}\\]`).test(line.trimStart()));
|
|
7
|
+
}
|
|
8
|
+
function marketplaceSource(text) {
|
|
9
|
+
for (const line of text.split('\n')) {
|
|
10
|
+
const match = /^\s*(\S+)\s+\(\d+ plugins?\)\s+(.+?)(?:\s+"[^"]*")?\s*$/.exec(line);
|
|
11
|
+
if (match && match[1] === MARKETPLACE) {
|
|
12
|
+
return match[2];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
function sourceWithoutFactoryPrefix(source) {
|
|
18
|
+
return source.replace(/^(?:github|url):/, '');
|
|
19
|
+
}
|
|
20
|
+
async function listPlugins(system) {
|
|
21
|
+
return mustProbeText(system, 'droid', ['plugin', 'list', '--scope', SCOPE]);
|
|
22
|
+
}
|
|
23
|
+
async function refreshMarketplace(system) {
|
|
24
|
+
const source = marketplaceSource(await mustProbeText(system, 'droid', ['plugin', 'marketplace', 'list']));
|
|
25
|
+
if (!source) {
|
|
26
|
+
await mustRun(system, 'droid', ['plugin', 'marketplace', 'add', GIT_URL]);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!isSameRepo(sourceWithoutFactoryPrefix(source), REPO)) {
|
|
30
|
+
blocked(`marketplace ${MARKETPLACE} is registered from ${redact(source)}, not ${REPO}`);
|
|
31
|
+
}
|
|
32
|
+
await mustRun(system, 'droid', ['plugin', 'marketplace', 'update', MARKETPLACE]);
|
|
33
|
+
}
|
|
34
|
+
export const factory = {
|
|
35
|
+
id: 'factory',
|
|
36
|
+
name: 'Factory Droid',
|
|
37
|
+
route: '.factory-plugin',
|
|
38
|
+
async detect(system) {
|
|
39
|
+
return (await system.which('droid')) !== null;
|
|
40
|
+
},
|
|
41
|
+
async status(system) {
|
|
42
|
+
const exec = await system.probe('droid', ['plugin', 'list', '--scope', SCOPE]);
|
|
43
|
+
if (exec.code !== 0) {
|
|
44
|
+
return { installed: null, detail: 'could not read `droid plugin list --scope user`', notes: [] };
|
|
45
|
+
}
|
|
46
|
+
return hasInstalledPlugin(exec.stdout) ?
|
|
47
|
+
{ installed: true, detail: PLUGIN_ID, notes: [] } :
|
|
48
|
+
{ installed: false, detail: 'not installed', notes: [] };
|
|
49
|
+
},
|
|
50
|
+
install(system) {
|
|
51
|
+
return guard(async () => {
|
|
52
|
+
await refreshMarketplace(system);
|
|
53
|
+
const wasInstalled = hasInstalledPlugin(await listPlugins(system)), verb = wasInstalled ? 'update' : 'install';
|
|
54
|
+
await mustRun(system, 'droid', ['plugin', verb, PLUGIN_ID, '--scope', SCOPE]);
|
|
55
|
+
return result('done', `${wasInstalled ? 'updated' : 'installed'} ${PLUGIN_ID}`, NEXT);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
remove(system) {
|
|
59
|
+
return guard(async () => {
|
|
60
|
+
if (!hasInstalledPlugin(await listPlugins(system))) {
|
|
61
|
+
return result('skipped', 'not installed');
|
|
62
|
+
}
|
|
63
|
+
await mustRun(system, 'droid', ['plugin', 'uninstall', PLUGIN_ID, '--scope', SCOPE]);
|
|
64
|
+
return result('done', `uninstalled ${PLUGIN_ID}`, NEXT);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
package/dist/hosts/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { claudeCode } from './claude-code.js';
|
|
2
2
|
import { codex } from './codex.js';
|
|
3
3
|
import { cursor } from './cursor.js';
|
|
4
|
+
import { factory } from './factory.js';
|
|
4
5
|
import { kimi } from './kimi.js';
|
|
5
6
|
import { opencode } from './opencode.js';
|
|
6
7
|
import { pi } from './pi.js';
|
|
7
|
-
export const HOSTS = [claudeCode, codex, cursor, kimi, opencode, pi];
|
|
8
|
+
export const HOSTS = [claudeCode, codex, cursor, factory, kimi, opencode, pi];
|
package/dist/hosts/shared.js
CHANGED
|
@@ -41,6 +41,14 @@ export async function mustProbeJson(system, command, args) {
|
|
|
41
41
|
}
|
|
42
42
|
return parsed;
|
|
43
43
|
}
|
|
44
|
+
/** Runs a read-only listing with no JSON mode; throws `StepFailed` if it fails. */
|
|
45
|
+
export async function mustProbeText(system, command, args) {
|
|
46
|
+
const exec = await system.probe(command, args);
|
|
47
|
+
if (exec.code !== 0) {
|
|
48
|
+
throw new StepFailed(result('failed', describeFailure(command, args, exec)));
|
|
49
|
+
}
|
|
50
|
+
return exec.stdout;
|
|
51
|
+
}
|
|
44
52
|
export function blocked(message) {
|
|
45
53
|
throw new StepFailed(result('blocked', message));
|
|
46
54
|
}
|
package/mcp.pi.json
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"description": "Postman workspaces, collections, specs, environments, mocks and monitors",
|
|
7
7
|
"headers": {
|
|
8
8
|
"X-Source": "postman-pi-plugin",
|
|
9
|
-
"X-Plugin-Version": "0.
|
|
10
|
-
"User-Agent": "postman-pi-plugin/0.
|
|
9
|
+
"X-Plugin-Version": "0.2.0-rc.0",
|
|
10
|
+
"User-Agent": "postman-pi-plugin/0.2.0-rc.0"
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postman/postman-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-rc.0",
|
|
4
4
|
"description": "Postman's API engineering skills for coding agents: a Pi package, and an npx installer that sets up Claude Code, Codex, Cursor, Kimi Code, OpenCode and Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"claude-code",
|
|
24
24
|
"codex",
|
|
25
25
|
"cursor",
|
|
26
|
+
"factory.ai",
|
|
26
27
|
"kimi",
|
|
27
28
|
"opencode",
|
|
28
29
|
"agent-plugin"
|