@unbrained/pm-cli 2026.5.6 → 2026.5.11
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/pm/extensions/.managed-extensions.json +2 -2
- package/.agents/pm/extensions/beads/runtime.js +4 -4
- package/.agents/pm/extensions/beads/runtime.ts +5 -5
- package/.agents/pm/extensions/todos/runtime.js +7 -7
- package/.agents/pm/extensions/todos/runtime.ts +10 -10
- package/.agents/skills/HARNESS_COMPATIBILITY.md +45 -0
- package/.agents/skills/README.md +21 -0
- package/.agents/skills/pm-developer/SKILL.md +73 -0
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +48 -0
- package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-extensions/SKILL.md +57 -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 +50 -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-user/SKILL.md +59 -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 +38 -0
- package/.pi/README.md +35 -0
- package/.pi/agents/pm-triage-agent.md +19 -0
- package/.pi/agents/pm-verification-agent.md +21 -0
- package/.pi/chains/pm-native-delivery.chain.md +11 -0
- package/.pi/extensions/pm-cli/index.js +387 -0
- package/.pi/prompts/pm-workflow.md +5 -0
- package/.pi/skills/pm-native/SKILL.md +44 -0
- package/.pi/skills/pm-release/SKILL.md +35 -0
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +13 -0
- package/PRD.md +16 -16
- package/README.md +30 -4
- package/dist/cli/argv-utils.d.ts +5 -0
- package/dist/cli/argv-utils.js +34 -0
- package/dist/cli/argv-utils.js.map +1 -0
- package/dist/cli/bootstrap-args.d.ts +15 -0
- package/dist/cli/bootstrap-args.js +211 -0
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +109 -3
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/claim.js +6 -6
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.js +9 -9
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments.d.ts +2 -0
- package/dist/cli/commands/comments.js +57 -8
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.js +40 -7
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.js +6 -3
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/contracts.d.ts +19 -0
- package/dist/cli/commands/contracts.js +36 -1
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.d.ts +2 -2
- package/dist/cli/commands/create.js +116 -55
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/docs.js +13 -6
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +3 -1
- package/dist/cli/commands/extension.js +174 -2
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.js +19 -12
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/get.js +5 -5
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/guide.d.ts +55 -0
- package/dist/cli/commands/guide.js +260 -0
- package/dist/cli/commands/guide.js.map +1 -0
- package/dist/cli/commands/health.js +1 -1
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history.js +30 -10
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +21 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learnings.js +3 -3
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
- package/dist/cli/commands/metadata-normalizers.js +37 -0
- package/dist/cli/commands/metadata-normalizers.js.map +1 -0
- package/dist/cli/commands/notes.js +3 -3
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/reindex.js +180 -156
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +2 -2
- package/dist/cli/commands/restore.js +44 -24
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/search.d.ts +2 -0
- package/dist/cli/commands/search.js +45 -26
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test-all.d.ts +2 -0
- package/dist/cli/commands/test-all.js +2 -0
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +1 -0
- package/dist/cli/commands/test.js +13 -5
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update.js +188 -157
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.js +1 -1
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +9 -1
- package/dist/cli/error-guidance.js +147 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/guide-topics.d.ts +25 -0
- package/dist/cli/guide-topics.js +283 -0
- package/dist/cli/guide-topics.js.map +1 -0
- package/dist/cli/help-content.js +25 -1
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.js +11 -1
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.js +69 -6
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +38 -1
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +17 -4
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-setup.js +15 -1
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/telemetry-flush.d.ts +2 -0
- package/dist/cli/telemetry-flush.js +4 -0
- package/dist/cli/telemetry-flush.js.map +1 -0
- package/dist/cli.js +1 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/extensions/extension-types.d.ts +72 -0
- package/dist/core/extensions/extension-types.js +24 -0
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -0
- package/dist/core/extensions/loader.js +766 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/history/history.js +32 -11
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/item/item-format.d.ts +2 -2
- package/dist/core/item/item-format.js +16 -16
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/lock/lock.js +2 -0
- package/dist/core/lock/lock.js.map +1 -1
- package/dist/core/schema/runtime-field-filters.js +1 -1
- package/dist/core/schema/runtime-field-filters.js.map +1 -1
- package/dist/core/schema/runtime-field-values.js +2 -2
- package/dist/core/schema/runtime-field-values.js.map +1 -1
- package/dist/core/schema/runtime-schema.d.ts +1 -1
- package/dist/core/schema/runtime-schema.js +3 -3
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/cache.js +7 -21
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/search/corpus.d.ts +13 -0
- package/dist/core/search/corpus.js +74 -0
- package/dist/core/search/corpus.js.map +1 -0
- package/dist/core/search/embedding-batches.js +90 -30
- package/dist/core/search/embedding-batches.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +18 -1
- package/dist/core/sentry/instrument.js +128 -12
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/constants.d.ts +1 -1
- package/dist/core/shared/constants.js +21 -1
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/errors.d.ts +8 -0
- package/dist/core/shared/errors.js.map +1 -1
- package/dist/core/shared/levenshtein.d.ts +1 -0
- package/dist/core/shared/levenshtein.js +37 -0
- package/dist/core/shared/levenshtein.js.map +1 -0
- package/dist/core/store/front-matter-cache.d.ts +1 -1
- package/dist/core/store/front-matter-cache.js +13 -13
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-format-migration.js +5 -2
- package/dist/core/store/item-format-migration.js.map +1 -1
- package/dist/core/store/item-store.js +16 -15
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/paths.js +35 -2
- package/dist/core/store/paths.js.map +1 -1
- package/dist/core/store/settings.js +216 -2
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.d.ts +1 -0
- package/dist/core/telemetry/runtime.js +102 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/core/test/item-test-run-tracking.js +2 -2
- package/dist/core/test/item-test-run-tracking.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +407 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/pi/native.d.ts +5 -0
- package/dist/pi/native.js +236 -0
- package/dist/pi/native.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +24 -2
- package/dist/sdk/cli-contracts.js +317 -2
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +12 -1
- package/dist/sdk/index.js +8 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/types.d.ts +51 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +15 -0
- package/docs/ARCHITECTURE.md +2 -2
- package/docs/CLAUDE_CODE_PLUGIN.md +225 -0
- package/docs/CODEX_PLUGIN.md +33 -0
- package/docs/COMMANDS.md +6 -2
- package/docs/CONFIGURATION.md +2 -8
- package/docs/EXTENSIONS.md +688 -0
- package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
- package/docs/PI_PACKAGE.md +141 -0
- package/docs/QUICKSTART.md +1 -0
- package/docs/README.md +30 -1
- package/docs/RELEASING.md +4 -2
- package/docs/SDK.md +444 -2
- package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
- package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
- package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
- package/docs/examples/policy-restricted-extension/README.md +74 -0
- package/docs/examples/policy-restricted-extension/index.js +21 -0
- package/docs/examples/policy-restricted-extension/manifest.json +21 -0
- package/docs/examples/policy-restricted-extension/package.json +8 -0
- package/docs/examples/sdk-app-embedding/README.md +39 -0
- package/docs/examples/sdk-app-embedding/package.json +9 -0
- package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
- package/docs/examples/sdk-contract-consumer/README.md +57 -0
- package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
- package/docs/examples/sdk-contract-consumer/package.json +10 -0
- package/docs/examples/starter-extension/README.md +57 -42
- package/docs/examples/starter-extension/manifest.json +15 -0
- package/marketplace.json +34 -0
- package/package.json +38 -4
- package/plugins/pm-cli-claude/.claude-plugin/plugin.json +23 -0
- package/plugins/pm-cli-claude/.mcp.json +12 -0
- package/plugins/pm-cli-claude/README.md +225 -0
- package/plugins/pm-cli-claude/agents/pm-coordinator.md +48 -0
- package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
- package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
- package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
- package/plugins/pm-cli-claude/commands/pm-audit.md +39 -0
- package/plugins/pm-cli-claude/commands/pm-calendar.md +41 -0
- package/plugins/pm-cli-claude/commands/pm-close-task.md +20 -0
- package/plugins/pm-cli-claude/commands/pm-developer.md +38 -0
- package/plugins/pm-cli-claude/commands/pm-init.md +44 -0
- package/plugins/pm-cli-claude/commands/pm-list.md +39 -0
- package/plugins/pm-cli-claude/commands/pm-new.md +36 -0
- package/plugins/pm-cli-claude/commands/pm-planner.md +51 -0
- package/plugins/pm-cli-claude/commands/pm-release.md +41 -0
- package/plugins/pm-cli-claude/commands/pm-search.md +21 -0
- package/plugins/pm-cli-claude/commands/pm-start-task.md +27 -0
- package/plugins/pm-cli-claude/commands/pm-status.md +15 -0
- package/plugins/pm-cli-claude/commands/pm-triage.md +35 -0
- package/plugins/pm-cli-claude/commands/pm-workflow.md +49 -0
- package/plugins/pm-cli-claude/hooks/hooks.json +17 -0
- package/plugins/pm-cli-claude/hooks/session-start.mjs +120 -0
- package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +60 -0
- package/plugins/pm-cli-claude/skills/pm-audit/SKILL.md +88 -0
- package/plugins/pm-cli-claude/skills/pm-developer/SKILL.md +116 -0
- package/plugins/pm-cli-claude/skills/pm-planner/SKILL.md +118 -0
- package/plugins/pm-cli-claude/skills/pm-release/SKILL.md +83 -0
- package/plugins/pm-cli-claude/skills/pm-workflow/SKILL.md +148 -0
- package/plugins/pm-cli-codex/.codex-plugin/plugin.json +45 -0
- package/plugins/pm-cli-codex/.mcp.json +14 -0
- package/plugins/pm-cli-codex/README.md +30 -0
- package/plugins/pm-cli-codex/assets/pm-cli-small.svg +4 -0
- package/plugins/pm-cli-codex/commands/pm-audit.md +8 -0
- package/plugins/pm-cli-codex/commands/pm-close-task.md +9 -0
- package/plugins/pm-cli-codex/commands/pm-start-task.md +9 -0
- package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +54 -0
- package/plugins/pm-cli-codex/skills/pm-auditor/SKILL.md +21 -0
- package/plugins/pm-cli-codex/skills/pm-auditor/agents/openai.yaml +6 -0
- package/plugins/pm-cli-codex/skills/pm-native/SKILL.md +57 -0
- package/plugins/pm-cli-codex/skills/pm-native/agents/openai.yaml +6 -0
- package/plugins/pm-cli-codex/skills/pm-release/SKILL.md +19 -0
- package/plugins/pm-cli-codex/skills/pm-release/agents/openai.yaml +6 -0
package/docs/SDK.md
CHANGED
|
@@ -1,5 +1,429 @@
|
|
|
1
1
|
# SDK
|
|
2
2
|
|
|
3
|
+
The supported programmatic surface is `@unbrained/pm-cli/sdk`.
|
|
4
|
+
|
|
5
|
+
Use this package for extension authoring, command/action contract discovery, and deterministic app or CI automation. Do not import private `src/core/...` modules from external integrations.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @unbrained/pm-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Core Exports
|
|
14
|
+
|
|
15
|
+
### Extension authoring
|
|
16
|
+
|
|
17
|
+
- `defineExtension`
|
|
18
|
+
- `EXTENSION_CAPABILITIES`
|
|
19
|
+
- `EXTENSION_CAPABILITY_CONTRACT`
|
|
20
|
+
- `EXTENSION_CAPABILITY_CONTRACT_VERSION`
|
|
21
|
+
- `EXTENSION_CAPABILITY_LEGACY_ALIASES`
|
|
22
|
+
- `EXTENSION_POLICY_MODES`
|
|
23
|
+
- `EXTENSION_POLICY_SURFACES`
|
|
24
|
+
- `EXTENSION_TRUST_MODES`
|
|
25
|
+
- `EXTENSION_SANDBOX_PROFILES`
|
|
26
|
+
|
|
27
|
+
### Command and action contracts
|
|
28
|
+
|
|
29
|
+
- `PM_CORE_COMMAND_NAMES`
|
|
30
|
+
- `PM_TOOL_ACTIONS`
|
|
31
|
+
- `PM_TOOL_PARAMETERS_SCHEMA`
|
|
32
|
+
- `PM_PI_TOOL_PARAMETERS_SCHEMA`
|
|
33
|
+
- `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
|
|
34
|
+
|
|
35
|
+
### Runtime contract constants
|
|
36
|
+
|
|
37
|
+
- `PM_EXTENSION_CAPABILITY_CONTRACTS`
|
|
38
|
+
- `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
|
|
39
|
+
- `PM_EXTENSION_POLICY_MODE_CONTRACTS`
|
|
40
|
+
- `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
|
|
41
|
+
- `PM_EXTENSION_TRUST_MODE_CONTRACTS`
|
|
42
|
+
- `PM_EXTENSION_SANDBOX_PROFILE_CONTRACTS`
|
|
43
|
+
|
|
44
|
+
### Type guards
|
|
45
|
+
|
|
46
|
+
- `isPmToolAction`
|
|
47
|
+
- `isPmExtensionCapabilityContract`
|
|
48
|
+
- `isPmExtensionServiceNameContract`
|
|
49
|
+
- `isPmExtensionPolicyModeContract`
|
|
50
|
+
- `isPmExtensionPolicySurfaceContract`
|
|
51
|
+
|
|
52
|
+
## Capability Mapping
|
|
53
|
+
|
|
54
|
+
- `commands` -> `registerCommand`
|
|
55
|
+
- `schema` -> `registerFlags`, `registerItemFields`, `registerItemTypes`, `registerMigration`
|
|
56
|
+
- `importers` -> `registerImporter`, `registerExporter`
|
|
57
|
+
- `search` -> `registerSearchProvider`, `registerVectorStoreAdapter`
|
|
58
|
+
- `hooks` -> `api.hooks.*`
|
|
59
|
+
- `parser` -> `registerParser`
|
|
60
|
+
- `preflight` -> `registerPreflight`
|
|
61
|
+
- `services` -> `registerService`
|
|
62
|
+
- `renderers` -> `registerRenderer`
|
|
63
|
+
|
|
64
|
+
## Extension Example
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
68
|
+
|
|
69
|
+
export default defineExtension({
|
|
70
|
+
activate(api) {
|
|
71
|
+
api.registerCommand({
|
|
72
|
+
name: "release audit",
|
|
73
|
+
action: "release-audit",
|
|
74
|
+
description: "Collect release-readiness diagnostics.",
|
|
75
|
+
intent: "Produce deterministic gate payloads for CI.",
|
|
76
|
+
flags: [{ long: "--strict", description: "Enable strict gate mode." }],
|
|
77
|
+
run: async (context) => ({
|
|
78
|
+
ok: true,
|
|
79
|
+
command: context.command,
|
|
80
|
+
strict: context.options.strict === true,
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Contracts-First Automation
|
|
88
|
+
|
|
89
|
+
Use runtime contracts for extension-aware schemas:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pm contracts --json
|
|
93
|
+
pm contracts --schema-only --json
|
|
94
|
+
pm contracts --command extension --flags-only --json
|
|
95
|
+
pm contracts --action create --schema-only --json
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Minimal script pattern:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { PM_TOOL_ACTION_PARAMETER_CONTRACTS, isPmToolAction } from "@unbrained/pm-cli/sdk";
|
|
102
|
+
import { spawnSync } from "node:child_process";
|
|
103
|
+
|
|
104
|
+
const action = "extension-reload";
|
|
105
|
+
if (!isPmToolAction(action)) throw new Error("Unsupported action");
|
|
106
|
+
const contract = PM_TOOL_ACTION_PARAMETER_CONTRACTS[action];
|
|
107
|
+
console.log(contract.required, contract.optional);
|
|
108
|
+
|
|
109
|
+
const result = spawnSync("pm", ["contracts", "--json"], { encoding: "utf8" });
|
|
110
|
+
if (result.status !== 0) throw new Error(result.stderr);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Compatibility Metadata
|
|
114
|
+
|
|
115
|
+
`pm contracts --json` includes compatibility metadata for extension integrations:
|
|
116
|
+
|
|
117
|
+
- `extension_contracts.trust_modes`
|
|
118
|
+
- `extension_contracts.sandbox_profiles`
|
|
119
|
+
- `extension_contracts.manifest_versions`
|
|
120
|
+
- `extension_contracts.compatibility`
|
|
121
|
+
- `action_availability[].policy_state`
|
|
122
|
+
|
|
123
|
+
Current compatibility model:
|
|
124
|
+
|
|
125
|
+
- manifest current: `v2`
|
|
126
|
+
- supported previous: `v1`
|
|
127
|
+
- strategy: `versioned_breaking`
|
|
128
|
+
|
|
129
|
+
## Runnable Examples
|
|
130
|
+
|
|
131
|
+
- `docs/examples/sdk-contract-consumer/`
|
|
132
|
+
- `docs/examples/sdk-app-embedding/`
|
|
133
|
+
- `docs/examples/ci/`
|
|
134
|
+
|
|
135
|
+
## Related Docs
|
|
136
|
+
|
|
137
|
+
- `docs/EXTENSIONS.md`
|
|
138
|
+
- `docs/CLAUDE_CODE_PLUGIN.md`
|
|
139
|
+
# SDK
|
|
140
|
+
|
|
141
|
+
The supported programmatic surface is `@unbrained/pm-cli/sdk`.
|
|
142
|
+
|
|
143
|
+
Use this for:
|
|
144
|
+
|
|
145
|
+
- extension authoring (`defineExtension`)
|
|
146
|
+
- command/action schema discovery (`PM_TOOL_PARAMETERS_SCHEMA`)
|
|
147
|
+
- runtime action contracts (`PM_TOOL_ACTION_PARAMETER_CONTRACTS`)
|
|
148
|
+
- capability/policy/trust/sandbox contract constants
|
|
149
|
+
|
|
150
|
+
Do not import private `src/core/...` modules from external integrations.
|
|
151
|
+
|
|
152
|
+
## Install
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npm install @unbrained/pm-cli
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Key Exports
|
|
159
|
+
|
|
160
|
+
### Extension Authoring
|
|
161
|
+
|
|
162
|
+
- `defineExtension`
|
|
163
|
+
- `EXTENSION_CAPABILITIES`
|
|
164
|
+
- `EXTENSION_POLICY_MODES`
|
|
165
|
+
- `EXTENSION_POLICY_SURFACES`
|
|
166
|
+
- `EXTENSION_TRUST_MODES`
|
|
167
|
+
- `EXTENSION_SANDBOX_PROFILES`
|
|
168
|
+
- `EXTENSION_CAPABILITY_CONTRACT`
|
|
169
|
+
- `EXTENSION_CAPABILITY_CONTRACT_VERSION`
|
|
170
|
+
- `EXTENSION_CAPABILITY_LEGACY_ALIASES`
|
|
171
|
+
|
|
172
|
+
### Command/Action Contracts
|
|
173
|
+
|
|
174
|
+
- `PM_CORE_COMMAND_NAMES`
|
|
175
|
+
- `PM_TOOL_ACTIONS`
|
|
176
|
+
- `PM_TOOL_PARAMETERS_SCHEMA`
|
|
177
|
+
- `PM_PI_TOOL_PARAMETERS_SCHEMA`
|
|
178
|
+
- `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
|
|
179
|
+
|
|
180
|
+
### Extension Runtime Contract Constants
|
|
181
|
+
|
|
182
|
+
- `PM_EXTENSION_CAPABILITY_CONTRACTS`
|
|
183
|
+
- `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
|
|
184
|
+
- `PM_EXTENSION_POLICY_MODE_CONTRACTS`
|
|
185
|
+
- `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
|
|
186
|
+
- `PM_EXTENSION_TRUST_MODE_CONTRACTS`
|
|
187
|
+
- `PM_EXTENSION_SANDBOX_PROFILE_CONTRACTS`
|
|
188
|
+
|
|
189
|
+
### Type Guards
|
|
190
|
+
|
|
191
|
+
- `isPmToolAction`
|
|
192
|
+
- `isPmExtensionCapabilityContract`
|
|
193
|
+
- `isPmExtensionServiceNameContract`
|
|
194
|
+
- `isPmExtensionPolicyModeContract`
|
|
195
|
+
- `isPmExtensionPolicySurfaceContract`
|
|
196
|
+
|
|
197
|
+
## Extension Example
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
201
|
+
|
|
202
|
+
export default defineExtension({
|
|
203
|
+
activate(api) {
|
|
204
|
+
api.registerCommand({
|
|
205
|
+
name: "release audit",
|
|
206
|
+
action: "release-audit",
|
|
207
|
+
description: "Collect release-readiness diagnostics.",
|
|
208
|
+
intent: "Produce deterministic gate payloads for CI.",
|
|
209
|
+
run: async (context) => ({
|
|
210
|
+
ok: true,
|
|
211
|
+
command: context.command,
|
|
212
|
+
}),
|
|
213
|
+
});
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Contracts-First Automation Pattern
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { PM_TOOL_ACTION_PARAMETER_CONTRACTS, isPmToolAction } from "@unbrained/pm-cli/sdk";
|
|
222
|
+
import { spawnSync } from "node:child_process";
|
|
223
|
+
|
|
224
|
+
const action = "extension-reload";
|
|
225
|
+
if (!isPmToolAction(action)) throw new Error("Unsupported action");
|
|
226
|
+
const contract = PM_TOOL_ACTION_PARAMETER_CONTRACTS[action];
|
|
227
|
+
console.log(contract.required, contract.optional);
|
|
228
|
+
|
|
229
|
+
const contracts = spawnSync("pm", ["contracts", "--json"], { encoding: "utf8" });
|
|
230
|
+
if (contracts.status !== 0) throw new Error(contracts.stderr);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Runtime Metadata Added For v2
|
|
234
|
+
|
|
235
|
+
`pm contracts --json` now includes richer extension metadata:
|
|
236
|
+
|
|
237
|
+
- `extension_contracts.trust_modes`
|
|
238
|
+
- `extension_contracts.sandbox_profiles`
|
|
239
|
+
- `extension_contracts.manifest_versions`
|
|
240
|
+
- `extension_contracts.compatibility`
|
|
241
|
+
- `action_availability[].policy_state` for extension-backed actions
|
|
242
|
+
|
|
243
|
+
Use these fields to gate CI and to route compatibility behavior in embedded runtimes.
|
|
244
|
+
|
|
245
|
+
## Versioned-Breaking Compatibility
|
|
246
|
+
|
|
247
|
+
Current contract compatibility model:
|
|
248
|
+
|
|
249
|
+
- `manifest` current: `v2`
|
|
250
|
+
- supported previous: `v1`
|
|
251
|
+
- strategy: `versioned_breaking`
|
|
252
|
+
|
|
253
|
+
Recommended migration flow:
|
|
254
|
+
|
|
255
|
+
1. read runtime contracts (`pm contracts --json`)
|
|
256
|
+
2. branch behavior by compatibility metadata
|
|
257
|
+
3. migrate manifests/policy to v2
|
|
258
|
+
4. enforce trust/sandbox policy gates in CI
|
|
259
|
+
|
|
260
|
+
## Runnable Examples
|
|
261
|
+
|
|
262
|
+
- contracts consumer: `docs/examples/sdk-contract-consumer/`
|
|
263
|
+
- app embedding runner: `docs/examples/sdk-app-embedding/`
|
|
264
|
+
- CI gates: `docs/examples/ci/`
|
|
265
|
+
|
|
266
|
+
## Related Docs
|
|
267
|
+
|
|
268
|
+
- `docs/EXTENSIONS.md`
|
|
269
|
+
- `docs/CLAUDE_CODE_PLUGIN.md`
|
|
270
|
+
# SDK
|
|
271
|
+
|
|
272
|
+
The stable integration surface is `@unbrained/pm-cli/sdk`. Use it for extension authoring, action/flag contract discovery, and deterministic app/CI automation.
|
|
273
|
+
|
|
274
|
+
## Install
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
npm install @unbrained/pm-cli
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
import {
|
|
282
|
+
defineExtension,
|
|
283
|
+
EXTENSION_CAPABILITIES,
|
|
284
|
+
EXTENSION_POLICY_MODES,
|
|
285
|
+
EXTENSION_POLICY_SURFACES,
|
|
286
|
+
PM_TOOL_ACTIONS,
|
|
287
|
+
PM_TOOL_PARAMETERS_SCHEMA,
|
|
288
|
+
PM_TOOL_ACTION_PARAMETER_CONTRACTS,
|
|
289
|
+
PM_EXTENSION_CAPABILITY_CONTRACTS,
|
|
290
|
+
PM_EXTENSION_SERVICE_NAME_CONTRACTS,
|
|
291
|
+
PM_EXTENSION_POLICY_MODE_CONTRACTS,
|
|
292
|
+
PM_EXTENSION_POLICY_SURFACE_CONTRACTS,
|
|
293
|
+
isPmToolAction,
|
|
294
|
+
isPmExtensionCapabilityContract,
|
|
295
|
+
} from "@unbrained/pm-cli/sdk";
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## What Is Exported
|
|
299
|
+
|
|
300
|
+
Core authoring exports:
|
|
301
|
+
|
|
302
|
+
- `defineExtension`
|
|
303
|
+
- `EXTENSION_CAPABILITIES`
|
|
304
|
+
- `EXTENSION_CAPABILITY_CONTRACT`
|
|
305
|
+
- `EXTENSION_POLICY_MODES`
|
|
306
|
+
- `EXTENSION_POLICY_SURFACES`
|
|
307
|
+
|
|
308
|
+
Command/action contract exports:
|
|
309
|
+
|
|
310
|
+
- `PM_CORE_COMMAND_NAMES`
|
|
311
|
+
- `PM_TOOL_ACTIONS`
|
|
312
|
+
- `PM_TOOL_PARAMETERS_SCHEMA`
|
|
313
|
+
- `PM_PI_TOOL_PARAMETERS_SCHEMA`
|
|
314
|
+
- `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
|
|
315
|
+
|
|
316
|
+
Extension runtime contract exports:
|
|
317
|
+
|
|
318
|
+
- `PM_EXTENSION_CAPABILITY_CONTRACTS`
|
|
319
|
+
- `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
|
|
320
|
+
- `PM_EXTENSION_POLICY_MODE_CONTRACTS`
|
|
321
|
+
- `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
|
|
322
|
+
|
|
323
|
+
Type guards:
|
|
324
|
+
|
|
325
|
+
- `isPmToolAction(value)`
|
|
326
|
+
- `isPmExtensionCapabilityContract(value)`
|
|
327
|
+
- `isPmExtensionServiceNameContract(value)`
|
|
328
|
+
- `isPmExtensionPolicyModeContract(value)`
|
|
329
|
+
- `isPmExtensionPolicySurfaceContract(value)`
|
|
330
|
+
|
|
331
|
+
## Capability Mapping
|
|
332
|
+
|
|
333
|
+
- `commands` -> `registerCommand`
|
|
334
|
+
- `schema` -> `registerFlags`, `registerItemFields`, `registerItemTypes`, `registerMigration`
|
|
335
|
+
- `importers` -> `registerImporter`, `registerExporter`
|
|
336
|
+
- `search` -> `registerSearchProvider`, `registerVectorStoreAdapter`
|
|
337
|
+
- `hooks` -> `api.hooks.*`
|
|
338
|
+
- `parser` -> `registerParser`
|
|
339
|
+
- `preflight` -> `registerPreflight`
|
|
340
|
+
- `services` -> `registerService`
|
|
341
|
+
- `renderers` -> `registerRenderer`
|
|
342
|
+
|
|
343
|
+
## Extension Authoring Example
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
347
|
+
|
|
348
|
+
export default defineExtension({
|
|
349
|
+
activate(api) {
|
|
350
|
+
api.registerCommand({
|
|
351
|
+
name: "release audit",
|
|
352
|
+
action: "release-audit",
|
|
353
|
+
description: "Collect release readiness diagnostics.",
|
|
354
|
+
intent: "provide deterministic audit payloads for CI gates",
|
|
355
|
+
examples: ["pm release audit --strict"],
|
|
356
|
+
failure_hints: ["Run pm extension --doctor --detail deep --trace on activation failures."],
|
|
357
|
+
flags: [{ long: "--strict", description: "Enable strict gate mode." }],
|
|
358
|
+
run: async (context) => ({
|
|
359
|
+
ok: true,
|
|
360
|
+
command: context.command,
|
|
361
|
+
strict: context.options.strict === true,
|
|
362
|
+
}),
|
|
363
|
+
});
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Programmatic Contracts (App/Script)
|
|
369
|
+
|
|
370
|
+
Use runtime `pm contracts` for extension-aware schemas:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
pm contracts --json
|
|
374
|
+
pm contracts --schema-only --json
|
|
375
|
+
pm contracts --command extension --flags-only --json
|
|
376
|
+
pm contracts --action create --schema-only --json
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The result includes:
|
|
380
|
+
|
|
381
|
+
- `actions`: runtime-invocable action list
|
|
382
|
+
- `action_availability`: invocable/disabled reasons
|
|
383
|
+
- `schema`: strict action-scoped JSON schema
|
|
384
|
+
- `command_flags`: merged core + extension + runtime field flags
|
|
385
|
+
- `extension_contracts`: capabilities/services/policy mode/surface contract metadata
|
|
386
|
+
|
|
387
|
+
## Robust Script Pattern
|
|
388
|
+
|
|
389
|
+
See runnable example: `docs/examples/sdk-contract-consumer/inspect-contracts.mjs`.
|
|
390
|
+
|
|
391
|
+
Minimal pattern:
|
|
392
|
+
|
|
393
|
+
1. Read contracts JSON.
|
|
394
|
+
2. Validate action exists in `actions`.
|
|
395
|
+
3. Validate required fields with `PM_TOOL_ACTION_PARAMETER_CONTRACTS`.
|
|
396
|
+
4. Execute the action only after preflight passes.
|
|
397
|
+
|
|
398
|
+
## CI/CD Pattern
|
|
399
|
+
|
|
400
|
+
Recommended gate sequence:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
pnpm build
|
|
404
|
+
pm contracts --schema-only --json > /tmp/pm-contracts.json
|
|
405
|
+
pm extension --doctor --project --detail summary --strict-exit
|
|
406
|
+
node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts
|
|
407
|
+
node scripts/run-tests.mjs coverage
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Reference workflow file:
|
|
411
|
+
|
|
412
|
+
- `docs/examples/ci/github-actions-pm-extension-gate.yml`
|
|
413
|
+
|
|
414
|
+
## Pi / Tooling Compatibility
|
|
415
|
+
|
|
416
|
+
For provider-safe schemas, use `PM_PI_TOOL_PARAMETERS_SCHEMA`. It is flat, non-`oneOf`, and designed for tool providers that reject advanced schema constructs.
|
|
417
|
+
|
|
418
|
+
The bundled Pi wrapper (`.pi/extensions/pm-cli/index.js`) consumes this schema directly to reduce contract drift.
|
|
419
|
+
|
|
420
|
+
## Related Docs
|
|
421
|
+
|
|
422
|
+
- `docs/EXTENSIONS.md`
|
|
423
|
+
- `docs/examples/starter-extension/README.md`
|
|
424
|
+
- `docs/examples/sdk-contract-consumer/README.md`
|
|
425
|
+
# SDK
|
|
426
|
+
|
|
3
427
|
The public SDK is exported from `@unbrained/pm-cli/sdk`. Use it for extension authoring and command-contract introspection. Do not import internal `src/core/...` modules from extensions.
|
|
4
428
|
|
|
5
429
|
## Agent Quick Context
|
|
@@ -7,6 +431,7 @@ The public SDK is exported from `@unbrained/pm-cli/sdk`. Use it for extension au
|
|
|
7
431
|
- Primary import: `@unbrained/pm-cli/sdk`.
|
|
8
432
|
- Runtime extension lifecycle is documented in [Extensions](EXTENSIONS.md).
|
|
9
433
|
- Exact command/action contracts are available through `pm contracts`.
|
|
434
|
+
- Local deep-dive routing is available through `pm guide sdk --depth deep`.
|
|
10
435
|
|
|
11
436
|
Tracked documentation work: [pm-1sb2](../.agents/pm/tasks/pm-1sb2.toon).
|
|
12
437
|
|
|
@@ -144,8 +569,8 @@ export default defineExtension({
|
|
|
144
569
|
name: "example-search",
|
|
145
570
|
async query(context) {
|
|
146
571
|
return context.documents
|
|
147
|
-
.filter((doc) => doc.
|
|
148
|
-
.map((doc) => ({ id: doc.
|
|
572
|
+
.filter((doc) => doc.metadata.title?.toLowerCase().includes(context.query.toLowerCase()))
|
|
573
|
+
.map((doc) => ({ id: doc.metadata.id, score: 0.5, matched_fields: ["title"] }));
|
|
149
574
|
},
|
|
150
575
|
});
|
|
151
576
|
},
|
|
@@ -166,6 +591,22 @@ pm contracts --action create --schema-only --json
|
|
|
166
591
|
|
|
167
592
|
Use the runtime command because active extensions can add command/action metadata.
|
|
168
593
|
|
|
594
|
+
## CLI Simplification Migration
|
|
595
|
+
|
|
596
|
+
The conservative full-surface simplification pass updated invocation parsing and error envelopes. Integration details are documented in:
|
|
597
|
+
|
|
598
|
+
- [CLI Simplification Migration](MIGRATION_CLI_SIMPLIFICATION.md)
|
|
599
|
+
|
|
600
|
+
For SDK and automation consumers, the key runtime change is the optional `recovery` object in CLI usage/error JSON payloads:
|
|
601
|
+
|
|
602
|
+
- `attempted_command`
|
|
603
|
+
- `normalized_args`
|
|
604
|
+
- `provided_fields`
|
|
605
|
+
- `missing`
|
|
606
|
+
- `suggested_retry`
|
|
607
|
+
|
|
608
|
+
Treat `recovery.suggested_retry` as the first-choice deterministic replay command when present.
|
|
609
|
+
|
|
169
610
|
## Authoring Pattern
|
|
170
611
|
|
|
171
612
|
- Keep handlers deterministic and JSON-like.
|
|
@@ -178,5 +619,6 @@ Use the runtime command because active extensions can add command/action metadat
|
|
|
178
619
|
## Related Docs
|
|
179
620
|
|
|
180
621
|
- [Extensions](EXTENSIONS.md)
|
|
622
|
+
- [CLI Simplification Migration](MIGRATION_CLI_SIMPLIFICATION.md)
|
|
181
623
|
- [Architecture](ARCHITECTURE.md)
|
|
182
624
|
- [starter extension](examples/starter-extension/README.md)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: pm-extension-gate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
extension-gate:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: 22
|
|
20
|
+
cache: pnpm
|
|
21
|
+
|
|
22
|
+
- name: Setup pnpm
|
|
23
|
+
uses: pnpm/action-setup@v4
|
|
24
|
+
with:
|
|
25
|
+
version: 10
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: pnpm install --frozen-lockfile
|
|
29
|
+
|
|
30
|
+
- name: Build
|
|
31
|
+
run: pnpm build
|
|
32
|
+
|
|
33
|
+
- name: Export contracts (schema + flags)
|
|
34
|
+
run: |
|
|
35
|
+
pm contracts --schema-only --json > contracts-schema.json
|
|
36
|
+
pm contracts --command extension --flags-only --json > contracts-extension-flags.json
|
|
37
|
+
pm contracts --json > contracts-runtime.json
|
|
38
|
+
|
|
39
|
+
- name: Verify extension contract compatibility metadata
|
|
40
|
+
run: |
|
|
41
|
+
node -e 'const fs=require("node:fs");const c=JSON.parse(fs.readFileSync("contracts-runtime.json","utf8"));if(!c.extension_contracts?.compatibility){throw new Error("missing extension compatibility metadata");}'
|
|
42
|
+
|
|
43
|
+
- name: Reload extensions
|
|
44
|
+
run: pm extension --reload --project --json
|
|
45
|
+
|
|
46
|
+
- name: Extension governance diagnostics gate
|
|
47
|
+
run: pm extension --doctor --project --detail summary --strict-exit
|
|
48
|
+
|
|
49
|
+
- name: Unit tests
|
|
50
|
+
run: node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts
|
|
51
|
+
|
|
52
|
+
- name: Coverage
|
|
53
|
+
run: node scripts/run-tests.mjs coverage
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
image: node:22
|
|
2
|
+
|
|
3
|
+
stages:
|
|
4
|
+
- build
|
|
5
|
+
- contracts
|
|
6
|
+
- extension_gate
|
|
7
|
+
- test
|
|
8
|
+
|
|
9
|
+
before_script:
|
|
10
|
+
- corepack enable
|
|
11
|
+
- corepack prepare pnpm@10 --activate
|
|
12
|
+
- pnpm install --frozen-lockfile
|
|
13
|
+
|
|
14
|
+
build:
|
|
15
|
+
stage: build
|
|
16
|
+
script:
|
|
17
|
+
- pnpm build
|
|
18
|
+
|
|
19
|
+
contracts:
|
|
20
|
+
stage: contracts
|
|
21
|
+
script:
|
|
22
|
+
- node dist/cli.js contracts --schema-only --json > contracts-schema.json
|
|
23
|
+
- node dist/cli.js contracts --command extension --flags-only --json > contracts-extension-flags.json
|
|
24
|
+
- node dist/cli.js contracts --json > contracts-runtime.json
|
|
25
|
+
artifacts:
|
|
26
|
+
paths:
|
|
27
|
+
- contracts-schema.json
|
|
28
|
+
- contracts-extension-flags.json
|
|
29
|
+
- contracts-runtime.json
|
|
30
|
+
|
|
31
|
+
extension_gate:
|
|
32
|
+
stage: extension_gate
|
|
33
|
+
script:
|
|
34
|
+
- node dist/cli.js extension --reload --project --json
|
|
35
|
+
- node dist/cli.js extension --doctor --project --detail summary --strict-exit --json
|
|
36
|
+
|
|
37
|
+
test:
|
|
38
|
+
stage: test
|
|
39
|
+
script:
|
|
40
|
+
- node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts
|
|
41
|
+
- node scripts/run-tests.mjs coverage
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
pipeline {
|
|
2
|
+
agent any
|
|
3
|
+
|
|
4
|
+
tools {
|
|
5
|
+
nodejs "node-22"
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
stages {
|
|
9
|
+
stage("Install") {
|
|
10
|
+
steps {
|
|
11
|
+
sh "corepack enable"
|
|
12
|
+
sh "corepack prepare pnpm@10 --activate"
|
|
13
|
+
sh "pnpm install --frozen-lockfile"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
stage("Build") {
|
|
18
|
+
steps {
|
|
19
|
+
sh "pnpm build"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
stage("Contracts") {
|
|
24
|
+
steps {
|
|
25
|
+
sh "node dist/cli.js contracts --schema-only --json > contracts-schema.json"
|
|
26
|
+
sh "node dist/cli.js contracts --command extension --flags-only --json > contracts-extension-flags.json"
|
|
27
|
+
sh "node dist/cli.js contracts --json > contracts-runtime.json"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
stage("Extension Gate") {
|
|
32
|
+
steps {
|
|
33
|
+
sh "node dist/cli.js extension --reload --project --json"
|
|
34
|
+
sh "node dist/cli.js extension --doctor --project --detail summary --strict-exit --json"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
stage("Tests") {
|
|
39
|
+
steps {
|
|
40
|
+
sh "node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts"
|
|
41
|
+
sh "node scripts/run-tests.mjs coverage"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Policy-Restricted Extension Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates governance policy behavior with real registrations.
|
|
4
|
+
|
|
5
|
+
The extension declares:
|
|
6
|
+
|
|
7
|
+
- `commands` (handler registration)
|
|
8
|
+
- `hooks` (beforeCommand)
|
|
9
|
+
- `services` (output_format override)
|
|
10
|
+
|
|
11
|
+
You can enforce policy so command/hooks remain allowed while service override is blocked.
|
|
12
|
+
|
|
13
|
+
## Run It
|
|
14
|
+
|
|
15
|
+
From repository root:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
mkdir -p .agents/pm/extensions
|
|
19
|
+
cp -R docs/examples/policy-restricted-extension .agents/pm/extensions/policy-restricted-extension
|
|
20
|
+
cd .agents/pm/extensions/policy-restricted-extension
|
|
21
|
+
npm install
|
|
22
|
+
cd -
|
|
23
|
+
pm extension --install --project .agents/pm/extensions/policy-restricted-extension
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Add policy in `.agents/pm/settings.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"extensions": {
|
|
31
|
+
"policy": {
|
|
32
|
+
"mode": "enforce",
|
|
33
|
+
"trust_mode": "enforce",
|
|
34
|
+
"require_provenance": true,
|
|
35
|
+
"trusted_extensions": ["policy-restricted-extension"],
|
|
36
|
+
"default_sandbox_profile": "restricted",
|
|
37
|
+
"allowed_extensions": ["policy-restricted-extension"],
|
|
38
|
+
"blocked_extensions": [],
|
|
39
|
+
"allowed_capabilities": [],
|
|
40
|
+
"blocked_capabilities": [],
|
|
41
|
+
"allowed_surfaces": [],
|
|
42
|
+
"blocked_surfaces": ["services.override"],
|
|
43
|
+
"allowed_commands": [],
|
|
44
|
+
"blocked_commands": [],
|
|
45
|
+
"allowed_actions": [],
|
|
46
|
+
"blocked_actions": [],
|
|
47
|
+
"allowed_services": [],
|
|
48
|
+
"blocked_services": ["output_format"],
|
|
49
|
+
"extension_overrides": [
|
|
50
|
+
{
|
|
51
|
+
"name": "policy-restricted-extension",
|
|
52
|
+
"require_trusted": true,
|
|
53
|
+
"require_provenance": true,
|
|
54
|
+
"sandbox_profile": "strict"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then validate:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pm extension --doctor --project --detail summary
|
|
66
|
+
pm policy demo
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Expected behavior:
|
|
70
|
+
|
|
71
|
+
- `pm policy demo` still works (command handler allowed).
|
|
72
|
+
- `extension --doctor` includes `extension_policy_blocked_registration`.
|
|
73
|
+
- `details.triage.policy_blocked_count` is greater than `0`.
|
|
74
|
+
- trust/provenance contract fields are visible in `pm contracts --json` metadata.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
2
|
+
|
|
3
|
+
export default defineExtension({
|
|
4
|
+
activate(api) {
|
|
5
|
+
api.registerCommand({
|
|
6
|
+
name: "policy demo",
|
|
7
|
+
action: "policy-demo",
|
|
8
|
+
description: "Emit a deterministic payload to validate policy-gated activation.",
|
|
9
|
+
run: async (context) => ({
|
|
10
|
+
ok: true,
|
|
11
|
+
command: context.command,
|
|
12
|
+
source: "policy-restricted-extension",
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
api.hooks.beforeCommand(() => {});
|
|
17
|
+
|
|
18
|
+
// This registration is intentionally useful for policy demos.
|
|
19
|
+
api.registerService("output_format", (payload) => payload);
|
|
20
|
+
},
|
|
21
|
+
});
|