@postman/postman-plugin 0.6.0 → 0.7.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 +2 -11
- package/dist/hosts/codex.js +1 -3
- package/mcp.pi.json +2 -2
- package/package.json +1 -1
- package/skills/api-engineer/SKILL.md +5 -5
- package/skills/workspaces/SKILL.md +18 -7
- package/dist/hosts/codex-hooks.js +0 -68
package/README.md
CHANGED
|
@@ -28,14 +28,6 @@ One command configures **Antigravity, Claude Code, Codex, GitHub Copilot CLI, Cu
|
|
|
28
28
|
Factory Droid, Kimi Code, OpenCode and Pi**. Run it again to update, `status` to see what's installed,
|
|
29
29
|
and `remove` to uninstall; `--agent <id>` limits any of them to one agent.
|
|
30
30
|
|
|
31
|
-
For Codex, installation also approves Postman's session-start hook, which adds
|
|
32
|
-
instructions for using Postman's API skills. There is no separate hook prompt
|
|
33
|
-
or dump of its instructions. Already trusted hooks are left alone. If Codex's
|
|
34
|
-
hook API is unavailable, installation continues with a note to approve the hook
|
|
35
|
-
inside Codex. Run the installer and Codex with the same `HOME` and `CODEX_HOME`;
|
|
36
|
-
hook approval applies to that profile. If Codex later refreshes the plugin from
|
|
37
|
-
`main` and its contents change, run the installer again to approve the update.
|
|
38
|
-
|
|
39
31
|
You can also use the following commands to install individually:
|
|
40
32
|
|
|
41
33
|
### Antigravity
|
|
@@ -71,9 +63,8 @@ codex plugin marketplace upgrade postman
|
|
|
71
63
|
codex plugin add postman@postman
|
|
72
64
|
```
|
|
73
65
|
|
|
74
|
-
These commands track `main
|
|
75
|
-
|
|
76
|
-
update.
|
|
66
|
+
These commands track `main`, and Codex updates the plugin from it when a
|
|
67
|
+
session starts.
|
|
77
68
|
|
|
78
69
|
### Cursor
|
|
79
70
|
|
package/dist/hosts/codex.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BRANCH, GIT_URL, REPO, isSameRepo, redact } from '../source.js';
|
|
2
2
|
import { StepFailed, blocked, failed, guard, mustProbeJson, mustRun, parseJson } from './shared.js';
|
|
3
3
|
import { result } from './types.js';
|
|
4
|
-
import { approvePostmanHook } from './codex-hooks.js';
|
|
5
4
|
// Codex names the marketplace after `.claude-plugin/marketplace.json`'s `name`.
|
|
6
5
|
// `npx plugins add` installs a second copy under its own `plugins-cli` marketplace.
|
|
7
6
|
const MARKETPLACE = 'postman', PLUGIN_ID = `postman@${MARKETPLACE}`, LEGACY_REF = 'codex-release', SHADOW_IDS = ['postman@plugins-cli'], NEXT = 'Restart Codex for the change to take effect.';
|
|
@@ -115,7 +114,7 @@ export const codex = {
|
|
|
115
114
|
}
|
|
116
115
|
const installed = plugins.find((plugin) => plugin.pluginId === PLUGIN_ID && plugin.installed !== false), notes = SHADOW_IDS.filter((id) => isInstalled(plugins, id)).map((id) => `${id} duplicates it and will be removed`);
|
|
117
116
|
if (installed && await registeredRef(system) === LEGACY_REF) {
|
|
118
|
-
notes.push(`marketplace ${MARKETPLACE} tracks ${LEGACY_REF} and will be re-added at ${BRANCH}
|
|
117
|
+
notes.push(`marketplace ${MARKETPLACE} tracks ${LEGACY_REF} and will be re-added at ${BRANCH}`);
|
|
119
118
|
}
|
|
120
119
|
return installed ?
|
|
121
120
|
{ installed: true, detail: `${PLUGIN_ID} ${installed.version ?? ''}`.trim(), notes } :
|
|
@@ -134,7 +133,6 @@ export const codex = {
|
|
|
134
133
|
await mustRun(system, 'codex', ['plugin', 'add', PLUGIN_ID, '--json']);
|
|
135
134
|
}
|
|
136
135
|
await removeInstalled(system, plugins, SHADOW_IDS);
|
|
137
|
-
await approvePostmanHook(system);
|
|
138
136
|
return result('done', `${wasInstalled ? 'updated' : 'installed'} ${PLUGIN_ID}`, NEXT);
|
|
139
137
|
});
|
|
140
138
|
},
|
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.7.0",
|
|
10
|
+
"User-Agent": "postman-pi-plugin/0.7.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.7.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, Factory Droid, OpenCode and Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,7 +45,8 @@ guesswork each time work resumes.
|
|
|
45
45
|
directories for API artifacts. It installs skills in `postman/skills` folder with guidance on designing, implementing, and validating APIs.
|
|
46
46
|
The command is idempotent and safe to rerun in an initialized project.
|
|
47
47
|
It creates an agent-scoped session that lets you record work without signing
|
|
48
|
-
in.
|
|
48
|
+
in. This session is temporary; see **workspaces**' "Claiming the work" for
|
|
49
|
+
signup guidance to preserve the work and its context before the session expires.
|
|
49
50
|
8. Another service's collection, environment, or mock can be added as a dependency
|
|
50
51
|
without replacing this repository's owning workspace binding. Use
|
|
51
52
|
**api-discovery** to bring in the relevant resource and preserve that separation.
|
|
@@ -69,10 +70,9 @@ for course correction. Recommend additional work only when it closes a material
|
|
|
69
70
|
gap, such as an untested behavior or a consumer affected by an interface change.
|
|
70
71
|
Decline unnecessary setup or scope and explain why it would not help the task.
|
|
71
72
|
|
|
72
|
-
Important:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
lifts it.
|
|
73
|
+
Important: When a CLI command returns a suggested action or blocks work on a plan,
|
|
74
|
+
subscription, credit, or usage restriction, follow **workspaces**' "CLI suggested
|
|
75
|
+
actions" to show the error and offer the appropriate next step.
|
|
76
76
|
|
|
77
77
|
## Verification
|
|
78
78
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workspaces
|
|
3
|
-
description: Use when initializing Postman in a repository, binding it to a Postman workspace, interpreting what `postman init` did, or
|
|
3
|
+
description: Use when initializing Postman in a repository, binding it to a Postman workspace, interpreting what `postman init` did, or handling CLI-suggested actions for authentication, plan, credits, usage quota, or subscription restrictions. Treats the workspace as the place where a service's API work and its evidence live, kept separate from the services it depends on. Use for requests such as "set up Postman in this repo" or "connect this repo to our workspace".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Workspaces
|
|
@@ -32,19 +32,30 @@ what result. Agents use it to read verified work instead of re-deriving it.
|
|
|
32
32
|
|
|
33
33
|
## Claiming the work
|
|
34
34
|
|
|
35
|
-
An agent can start in a
|
|
35
|
+
An agent can start in a temporary session without signing in. Work done there and
|
|
36
|
+
its context may be lost or become inaccessible when the temporary session expires unless the user
|
|
37
|
+
claims it with `postman signup`. When the CLI prints its temporary-session
|
|
38
|
+
reminder, explain this to the user and offer to start signup.
|
|
39
|
+
|
|
36
40
|
When free credits or a plan limit stop an operation, retrying won't help; the
|
|
37
41
|
person claiming the work is what lets it continue. Wording such as "usage limit
|
|
38
42
|
exceeded", "usage quota has been exceeded", a limit "reached", "breached" or
|
|
39
43
|
"exceeded" for the account, team, or plan, or an operation that "does not allow
|
|
40
44
|
more than" or "requires at least" a stated amount signals one. A temporary rate
|
|
41
|
-
limit or a fixed per-resource validation cap does not.
|
|
45
|
+
limit or a fixed per-resource validation cap does not.
|
|
46
|
+
|
|
47
|
+
Do not retry the operations that were stopped for these reasons,
|
|
48
|
+
The Postman CLI will also suggest a next step in most of these cases.
|
|
49
|
+
Which the agent can pick up and suggest to the user and offer to start
|
|
50
|
+
that process for them.
|
|
51
|
+
|
|
52
|
+
If the CLI does not suggest a next step. Check which session the
|
|
42
53
|
CLI is using:
|
|
43
54
|
|
|
44
|
-
- Guest session: tell the user, in its own paragraph, that signing up for a
|
|
45
|
-
Postman account claims the work done so far and
|
|
46
|
-
continue. Offer to start signup for them; the CLI can produce
|
|
47
|
-
over and waits while they finish in the browser.
|
|
55
|
+
- Temporary/Guest session: tell the user, in its own paragraph, that signing up for a
|
|
56
|
+
Postman account claims the work done so far and its context, and adds the
|
|
57
|
+
credits needed to continue. Offer to start signup for them; the CLI can produce
|
|
58
|
+
a link to hand over and waits while they finish in the browser.
|
|
48
59
|
- Signed-in account: tell the user, in its own paragraph, that they need to
|
|
49
60
|
upgrade their plan at https://postman.postman.co/settings/team/billing.
|
|
50
61
|
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
export const POSTMAN_HOOK_KEY = 'postman@postman:hooks/codex-hooks.json:session_start:0:0';
|
|
3
|
-
async function postmanHook(rpc, cwd) {
|
|
4
|
-
const result = await rpc.request('hooks/list', { cwds: [cwd] });
|
|
5
|
-
if (!Array.isArray(result?.data) || result.data.some((entry) => !Array.isArray(entry.hooks) || entry.errors?.length)) {
|
|
6
|
-
throw new Error('hooks/list returned no usable hook listing');
|
|
7
|
-
}
|
|
8
|
-
const hooks = result.data.flatMap((entry) => entry.hooks).filter((hook) => hook.key === POSTMAN_HOOK_KEY);
|
|
9
|
-
if (hooks.length > 1) {
|
|
10
|
-
throw new Error('hooks/list returned more than one Postman session-start hook');
|
|
11
|
-
}
|
|
12
|
-
return hooks[0];
|
|
13
|
-
}
|
|
14
|
-
const trustEdit = (hash) => ({
|
|
15
|
-
edits: [{ keyPath: 'hooks.state', value: { [POSTMAN_HOOK_KEY]: { trusted_hash: hash } }, mergeStrategy: 'upsert' }],
|
|
16
|
-
reloadUserConfig: true
|
|
17
|
-
});
|
|
18
|
-
/** Approves only Postman's current hook after installation; unsupported APIs never fail the install. */
|
|
19
|
-
export async function approvePostmanHook(system) {
|
|
20
|
-
const note = (message) => system.log(` note: ${message}`);
|
|
21
|
-
let writeAttempted = false;
|
|
22
|
-
if (system.dryRun) {
|
|
23
|
-
note('Would inspect and approve Postman\'s current session-start hook after installation through codex app-server:');
|
|
24
|
-
system.log(` config/batchWrite ${JSON.stringify(trustEdit('<currentHash from hooks/list>'))}`);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
try {
|
|
28
|
-
await system.withJsonRpc('codex', ['app-server'], async (rpc) => {
|
|
29
|
-
// Version of this small protocol client, independent of the plugin's release.
|
|
30
|
-
await rpc.request('initialize', { clientInfo: { name: 'postman-plugin-installer', version: '1' } });
|
|
31
|
-
rpc.notify('initialized');
|
|
32
|
-
const hook = await postmanHook(rpc, system.cwd);
|
|
33
|
-
if (!hook) {
|
|
34
|
-
note('Postman\'s session-start hook was not found; hook approval skipped.');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (hook.trustStatus === 'trusted') {
|
|
38
|
-
note('Postman\'s Codex session-start hook is already trusted.');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (!['untrusted', 'modified'].includes(hook.trustStatus) || !hook.currentHash || typeof hook.currentHash !== 'string') {
|
|
42
|
-
throw new Error('Postman\'s hook has an unsupported trust status or hash');
|
|
43
|
-
}
|
|
44
|
-
// Confirm the installed instructions are present before approving their hook.
|
|
45
|
-
const mandateFile = path.resolve(path.dirname(hook.sourcePath), 'session-start-context.md'), mandate = await system.readFile(mandateFile);
|
|
46
|
-
if (!mandate?.trim()) {
|
|
47
|
-
throw new Error('could not read the installed hooks/session-start-context.md');
|
|
48
|
-
}
|
|
49
|
-
// Startup can refresh marketplaces. A changed hash needs another check,
|
|
50
|
-
// rather than approving a different version from the one inspected above.
|
|
51
|
-
const current = await postmanHook(rpc, system.cwd);
|
|
52
|
-
if (!current || current.currentHash !== hook.currentHash || !['untrusted', 'modified'].includes(current.trustStatus)) {
|
|
53
|
-
note('Postman\'s hook changed while checking it; approval skipped. Re-run to approve the current version.');
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
writeAttempted = true;
|
|
57
|
-
await rpc.request('config/batchWrite', trustEdit(hook.currentHash));
|
|
58
|
-
const after = await postmanHook(rpc, system.cwd);
|
|
59
|
-
note(after?.trustStatus === 'trusted' && after.currentHash === hook.currentHash ?
|
|
60
|
-
'Approved Postman\'s Codex session-start hook.' :
|
|
61
|
-
'Codex accepted the approval write, but the hook is not confirmed trusted. Review it in Codex.');
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
// Older Codex releases may lack app-server or hooks/list. Installation still succeeds.
|
|
66
|
-
note(`Hook approval ${writeAttempted ? 'could not be confirmed' : 'skipped'}: ${error instanceof Error ? error.message : String(error)}. Review the hook in Codex.`);
|
|
67
|
-
}
|
|
68
|
-
}
|