pi-profile-switch 0.6.0 → 0.8.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 +52 -54
- package/README.zh-CN.md +52 -54
- package/bin/pi-profile.ts +10 -4
- package/bin/postinstall.js +26 -28
- package/examples/ask.json +13 -0
- package/examples/example.json +30 -35
- package/package.json +1 -1
- package/schemas/profiles.schema.json +50 -76
- package/src/launcher/runtime-cleanup.ts +210 -29
- package/src/profile-catalog-store.ts +51 -74
- package/src/profile-catalog.ts +81 -50
- package/src/project-trust.ts +1 -1
- package/src/switching/profile-crud.ts +3 -6
- package/src/workspace.ts +3 -16
- package/examples/profiles.json +0 -18
package/README.md
CHANGED
|
@@ -27,72 +27,62 @@ pi-profile ask -- --model openai/gpt-5.4
|
|
|
27
27
|
|
|
28
28
|
## Define your own profiles
|
|
29
29
|
|
|
30
|
-
Profiles live in two JSON
|
|
30
|
+
Profiles live in two directories, with one JSON file per profile:
|
|
31
31
|
|
|
32
|
-
|
|
|
32
|
+
| Path | Scope |
|
|
33
33
|
| --- | --- |
|
|
34
|
-
| `~/.pi-profile-switch/profiles
|
|
35
|
-
| `<project>/.pi/profiles
|
|
34
|
+
| `~/.pi-profile-switch/profiles/<name>.json` | Global, all projects. `PI_PROFILE_SWITCH_DIR` overrides the workspace root. |
|
|
35
|
+
| `<project>/.pi/profiles/<name>.json` | Project-level, trusted projects only. |
|
|
36
36
|
|
|
37
|
-
Create or change a profile by editing
|
|
37
|
+
Create or change a profile by editing or creating a `<name>.json` file directly — schema: [`schemas/profiles.schema.json`](schemas/profiles.schema.json).
|
|
38
38
|
|
|
39
|
-
On install, pi-profile-switch seeds the global
|
|
39
|
+
On install, pi-profile-switch seeds the global `profiles/` directory with a starter **`ask`** profile (`ask.json`) — read-only Q&A and code exploration. It assumes nothing about your setup; edit or delete it freely:
|
|
40
40
|
|
|
41
41
|
```json
|
|
42
42
|
{
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"extensions": [],
|
|
50
|
-
"tools": ["read", "grep", "find", "ls"],
|
|
51
|
-
"instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
|
|
52
|
-
}
|
|
53
|
-
}
|
|
43
|
+
"label": "Ask & Discuss",
|
|
44
|
+
"description": "Read-only Q&A and code exploration; no file modifications or command execution",
|
|
45
|
+
"skills": [],
|
|
46
|
+
"extensions": [],
|
|
47
|
+
"tools": ["read", "grep", "find", "ls"],
|
|
48
|
+
"instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
|
|
54
49
|
}
|
|
55
50
|
```
|
|
56
51
|
|
|
57
|
-
One profile can use every field at once. This example `impl` profile loads the TDD skill, the mcp-scripting skill (shipped by pi-mcp-adapter), and your internal skills; wires up two MCP servers; allows the built-in tools plus both servers' MCP tools by glob; and pins the model and standing instructions:
|
|
52
|
+
One profile can use every field at once. This example `impl` profile (`impl.json`) loads the TDD skill, the mcp-scripting skill (shipped by pi-mcp-adapter), and your internal skills; wires up two MCP servers; allows the built-in tools plus both servers' MCP tools by glob; and pins the model and standing instructions:
|
|
58
53
|
|
|
59
54
|
```json
|
|
60
55
|
{
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"defaultModel": "claude-sonnet-4-5",
|
|
92
|
-
"defaultThinkingLevel": "high",
|
|
93
|
-
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
94
|
-
}
|
|
95
|
-
}
|
|
56
|
+
"label": "Implementation",
|
|
57
|
+
"description": "Full-powered implementation profile: every available field, pinned model",
|
|
58
|
+
"skills": [
|
|
59
|
+
"tdd",
|
|
60
|
+
"internal-*",
|
|
61
|
+
"mcp-scripting"
|
|
62
|
+
],
|
|
63
|
+
"extensions": [
|
|
64
|
+
"pi-mcp-adapter"
|
|
65
|
+
],
|
|
66
|
+
"mcps": [
|
|
67
|
+
"github",
|
|
68
|
+
"linear"
|
|
69
|
+
],
|
|
70
|
+
"tools": [
|
|
71
|
+
"read",
|
|
72
|
+
"grep",
|
|
73
|
+
"find",
|
|
74
|
+
"ls",
|
|
75
|
+
"bash",
|
|
76
|
+
"edit",
|
|
77
|
+
"write",
|
|
78
|
+
"mcp__*",
|
|
79
|
+
"github_*",
|
|
80
|
+
"linear_*"
|
|
81
|
+
],
|
|
82
|
+
"defaultProvider": "anthropic",
|
|
83
|
+
"defaultModel": "claude-sonnet-4-5",
|
|
84
|
+
"defaultThinkingLevel": "high",
|
|
85
|
+
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
96
86
|
}
|
|
97
87
|
```
|
|
98
88
|
|
|
@@ -103,7 +93,15 @@ How fields resolve:
|
|
|
103
93
|
- `mcps` references servers from your pi-mcp-adapter configuration; connection details stay in the adapter's own config.
|
|
104
94
|
- Any field you omit keeps plain Pi behavior.
|
|
105
95
|
|
|
106
|
-
The files in [`examples/`](examples/) mirror the two profiles above: `
|
|
96
|
+
The files in [`examples/`](examples/) mirror the two profiles above: `ask.json` is the seeded starter, `example.json` the full-field demo.
|
|
97
|
+
|
|
98
|
+
### Migrating from earlier versions
|
|
99
|
+
|
|
100
|
+
If you used an earlier version that stored all profiles in a single `profiles.json` (`schemaVersion: 1`), migrate manually by creating a file for each profile under the `profiles/` directory:
|
|
101
|
+
|
|
102
|
+
1. Create directory `~/.pi-profile-switch/profiles/` (or `<project>/.pi/profiles/`).
|
|
103
|
+
2. For each key `<name>` in your old `profiles.json`'s `profiles` object, save its value directly as `<name>.json`.
|
|
104
|
+
3. Drop the outer `schemaVersion` and `profiles` envelope.
|
|
107
105
|
|
|
108
106
|
## Commands
|
|
109
107
|
|
package/README.zh-CN.md
CHANGED
|
@@ -27,72 +27,62 @@ pi-profile ask -- --model openai/gpt-5.4
|
|
|
27
27
|
|
|
28
28
|
## 自定义 profile
|
|
29
29
|
|
|
30
|
-
profile
|
|
30
|
+
profile 保存在两个目录中,每个 profile 对应一个独立 JSON 文件:
|
|
31
31
|
|
|
32
|
-
|
|
|
32
|
+
| 路径 | 作用域 |
|
|
33
33
|
| --- | --- |
|
|
34
|
-
| `~/.pi-profile-switch/profiles
|
|
35
|
-
| `<项目>/.pi/profiles
|
|
34
|
+
| `~/.pi-profile-switch/profiles/<name>.json` | 全局,对所有项目生效。`PI_PROFILE_SWITCH_DIR` 可自定义根目录。 |
|
|
35
|
+
| `<项目>/.pi/profiles/<name>.json` | 项目级,仅对已信任项目生效。 |
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
直接编辑或新建 `<name>.json` 即可创建或修改 profile——schema 见 [`schemas/profiles.schema.json`](schemas/profiles.schema.json)。
|
|
38
38
|
|
|
39
|
-
安装时,pi-profile-switch
|
|
39
|
+
安装时,pi-profile-switch 会向全局 `profiles/` 目录播种一个初始 **`ask`** profile(`ask.json`)——只读的问答与代码走读模式。它不假设你安装过任何插件,可随意修改或删除:
|
|
40
40
|
|
|
41
41
|
```json
|
|
42
42
|
{
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"extensions": [],
|
|
50
|
-
"tools": ["read", "grep", "find", "ls"],
|
|
51
|
-
"instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
|
|
52
|
-
}
|
|
53
|
-
}
|
|
43
|
+
"label": "Ask & Discuss",
|
|
44
|
+
"description": "Read-only Q&A and code exploration; no file modifications or command execution",
|
|
45
|
+
"skills": [],
|
|
46
|
+
"extensions": [],
|
|
47
|
+
"tools": ["read", "grep", "find", "ls"],
|
|
48
|
+
"instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
|
|
54
49
|
}
|
|
55
50
|
```
|
|
56
51
|
|
|
57
|
-
一个 profile 可以同时使用全部字段。下面这个 `impl` profile
|
|
52
|
+
一个 profile 可以同时使用全部字段。下面这个 `impl` profile 示例(`impl.json`)加载 TDD skill、mcp-scripting skill(pi-mcp-adapter 自带)和你的内部 skills;接入两个 MCP server;tool 白名单用 glob 覆盖内建工具和这两个 server 的 MCP 工具;并钉住模型与常驻 instructions:
|
|
58
53
|
|
|
59
54
|
```json
|
|
60
55
|
{
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"defaultModel": "claude-sonnet-4-5",
|
|
92
|
-
"defaultThinkingLevel": "high",
|
|
93
|
-
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
94
|
-
}
|
|
95
|
-
}
|
|
56
|
+
"label": "Implementation",
|
|
57
|
+
"description": "Full-powered implementation profile: every available field, pinned model",
|
|
58
|
+
"skills": [
|
|
59
|
+
"tdd",
|
|
60
|
+
"internal-*",
|
|
61
|
+
"mcp-scripting"
|
|
62
|
+
],
|
|
63
|
+
"extensions": [
|
|
64
|
+
"pi-mcp-adapter"
|
|
65
|
+
],
|
|
66
|
+
"mcps": [
|
|
67
|
+
"github",
|
|
68
|
+
"linear"
|
|
69
|
+
],
|
|
70
|
+
"tools": [
|
|
71
|
+
"read",
|
|
72
|
+
"grep",
|
|
73
|
+
"find",
|
|
74
|
+
"ls",
|
|
75
|
+
"bash",
|
|
76
|
+
"edit",
|
|
77
|
+
"write",
|
|
78
|
+
"mcp__*",
|
|
79
|
+
"github_*",
|
|
80
|
+
"linear_*"
|
|
81
|
+
],
|
|
82
|
+
"defaultProvider": "anthropic",
|
|
83
|
+
"defaultModel": "claude-sonnet-4-5",
|
|
84
|
+
"defaultThinkingLevel": "high",
|
|
85
|
+
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
96
86
|
}
|
|
97
87
|
```
|
|
98
88
|
|
|
@@ -103,7 +93,15 @@ profile 定义在两个 JSON 文件中,均可选:
|
|
|
103
93
|
- `mcps` 引用 pi-mcp-adapter 配置中的 server;连接细节留在 adapter 自己的配置里。
|
|
104
94
|
- 未写的字段保持原生 Pi 行为。
|
|
105
95
|
|
|
106
|
-
[`examples/`](examples/) 中的两个文件与上面一一对应:`
|
|
96
|
+
[`examples/`](examples/) 中的两个文件与上面一一对应:`ask.json` 是播种的初始 profile,`example.json` 是全字段演示。
|
|
97
|
+
|
|
98
|
+
### 从旧版本迁移
|
|
99
|
+
|
|
100
|
+
如果你之前使用了把全部 profile 存在单个 `profiles.json`(含 `schemaVersion: 1`)的旧版本,请手动把每个 profile 拆分到 `profiles/` 目录:
|
|
101
|
+
|
|
102
|
+
1. 创建 `~/.pi-profile-switch/profiles/`(或 `<项目>/.pi/profiles/`)目录。
|
|
103
|
+
2. 将旧 `profiles.json` 中 `profiles` 下的每个 `<name>` 键值提取为独立的 `<name>.json` 文件。
|
|
104
|
+
3. 去除外层的 `schemaVersion` 与 `profiles` 信封,文件顶层即为裸 profile 定义。
|
|
107
105
|
|
|
108
106
|
## 命令
|
|
109
107
|
|
package/bin/pi-profile.ts
CHANGED
|
@@ -37,10 +37,16 @@ try {
|
|
|
37
37
|
console.error(`pi-profile: warning: ${warning}`);
|
|
38
38
|
}
|
|
39
39
|
// Stale per-launch instance dirs (dead pid, or no pid past the grace
|
|
40
|
-
// window) are swept before this launch materializes its own.
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
40
|
+
// window) are swept before this launch materializes its own. Unrecognized
|
|
41
|
+
// entries are dispositioned per content scan: kept + reported when they
|
|
42
|
+
// reference the instance path or cannot be cleared, adopted into the real
|
|
43
|
+
// agent dir, or deleted on a name conflict (real wins) — all with a stderr
|
|
44
|
+
// notice (ADR-0012). Best-effort: sweep errors never block the launch.
|
|
45
|
+
const sweep = await sweepStaleInstances(agentDir);
|
|
46
|
+
for (const notice of sweep.notices) {
|
|
47
|
+
console.error(`pi-profile: notice: ${notice}`);
|
|
48
|
+
}
|
|
49
|
+
for (const warning of sweep.warnings) {
|
|
44
50
|
console.error(`pi-profile: warning: ${warning}`);
|
|
45
51
|
}
|
|
46
52
|
const generated = await generateRuntimeDir(plan, { agentDir, discovery, projectDir });
|
package/bin/postinstall.js
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* postinstall: seed the global catalog with the default
|
|
3
|
+
* postinstall: seed the global catalog with the default starter profile.
|
|
4
4
|
*
|
|
5
5
|
* Runs at package install time (`npm install pi-profile-switch` / `pi install`).
|
|
6
6
|
* Idempotent and conservative:
|
|
7
|
-
* - Writes the shipped `examples/
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* one written concurrently — is never touched).
|
|
11
|
-
* - Skips entirely when a legacy `~/.pi/agent/profiles.json` exists, because
|
|
12
|
-
* the resolver still falls back to it and a new preferred-path file would
|
|
13
|
-
* silently shadow it (see src/workspace.ts resolveGlobalProfilesPath).
|
|
7
|
+
* - Writes the shipped `examples/ask.json` starter profile to the
|
|
8
|
+
* profiles dir ONLY when no .json profile exists there yet
|
|
9
|
+
* (COPYFILE_EXCL; an existing file — including one written concurrently — is never touched).
|
|
14
10
|
* - Never fails the install: errors are downgraded to a warning.
|
|
15
11
|
*
|
|
16
12
|
* This module is plain Node ESM (no jiti/TS): npm may run postinstall in a
|
|
17
13
|
* context where only plain JS is safe. The path rules intentionally mirror
|
|
18
14
|
* src/workspace.ts — keep them in sync.
|
|
19
15
|
*/
|
|
20
|
-
import {
|
|
16
|
+
import { copyFile, mkdir, readdir } from "node:fs/promises";
|
|
21
17
|
import { constants } from "node:fs";
|
|
22
18
|
import { homedir } from "node:os";
|
|
23
19
|
import path from "node:path";
|
|
24
20
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
25
21
|
|
|
26
|
-
const DEFAULT_TEMPLATE = fileURLToPath(new URL("../examples/
|
|
22
|
+
const DEFAULT_TEMPLATE = fileURLToPath(new URL("../examples/ask.json", import.meta.url));
|
|
27
23
|
|
|
28
24
|
/** Mirrors getProfileSwitchDir() in src/workspace.ts.
|
|
29
25
|
* @param {NodeJS.ProcessEnv} env */
|
|
@@ -33,38 +29,40 @@ function profileSwitchDir(env) {
|
|
|
33
29
|
return path.join(homedir(), ".pi-profile-switch");
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
/**
|
|
32
|
+
/** Mirrors getGlobalProfilesDir() in src/workspace.ts.
|
|
37
33
|
* @param {NodeJS.ProcessEnv} env */
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
return path.join(agentDir, "profiles.json");
|
|
34
|
+
function globalProfilesDir(env) {
|
|
35
|
+
return path.join(profileSwitchDir(env), "profiles");
|
|
41
36
|
}
|
|
42
37
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
38
|
+
/** Checks whether the directory exists and contains any .json files.
|
|
39
|
+
* @param {string} dir */
|
|
40
|
+
async function hasAnyJsonProfiles(dir) {
|
|
45
41
|
try {
|
|
46
|
-
await
|
|
47
|
-
return
|
|
42
|
+
const entries = await readdir(dir);
|
|
43
|
+
return entries.some((name) => name.endsWith(".json"));
|
|
48
44
|
} catch {
|
|
49
45
|
return false;
|
|
50
46
|
}
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
/** @typedef {{ path: string, written: boolean
|
|
49
|
+
/** @typedef {{ path: string, written: boolean }} InstallResult */
|
|
54
50
|
|
|
55
51
|
/**
|
|
56
|
-
* Seeds the default
|
|
57
|
-
*
|
|
52
|
+
* Seeds the default starter profile. Safe to call repeatedly; only writes
|
|
53
|
+
* if no .json files exist in the global profiles directory.
|
|
58
54
|
* @param {{ env?: NodeJS.ProcessEnv }} [options]
|
|
59
55
|
* @returns {Promise<InstallResult>}
|
|
60
56
|
*/
|
|
61
57
|
export async function installDefaultProfiles({ env = process.env } = {}) {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
const dir = globalProfilesDir(env);
|
|
59
|
+
const target = path.join(dir, "ask.json");
|
|
60
|
+
|
|
61
|
+
if (await hasAnyJsonProfiles(dir)) {
|
|
62
|
+
return { path: target, written: false };
|
|
66
63
|
}
|
|
67
|
-
|
|
64
|
+
|
|
65
|
+
await mkdir(dir, { recursive: true });
|
|
68
66
|
try {
|
|
69
67
|
await copyFile(DEFAULT_TEMPLATE, target, constants.COPYFILE_EXCL);
|
|
70
68
|
} catch (error) {
|
|
@@ -80,10 +78,10 @@ const invokedDirectly = process.argv[1] !== undefined && import.meta.url === pat
|
|
|
80
78
|
if (invokedDirectly) {
|
|
81
79
|
installDefaultProfiles().then(
|
|
82
80
|
(result) => {
|
|
83
|
-
if (result.written) console.log(`pi-profile: seeded
|
|
81
|
+
if (result.written) console.log(`pi-profile: seeded starter profile at ${result.path}`);
|
|
84
82
|
},
|
|
85
83
|
(error) => {
|
|
86
|
-
console.warn(`pi-profile: could not seed
|
|
84
|
+
console.warn(`pi-profile: could not seed starter profile: ${error instanceof Error ? error.message : error}`);
|
|
87
85
|
},
|
|
88
86
|
);
|
|
89
87
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"label": "Ask & Discuss",
|
|
3
|
+
"description": "Read-only Q&A and code exploration; no file modifications or command execution",
|
|
4
|
+
"skills": [],
|
|
5
|
+
"extensions": [],
|
|
6
|
+
"tools": [
|
|
7
|
+
"read",
|
|
8
|
+
"grep",
|
|
9
|
+
"find",
|
|
10
|
+
"ls"
|
|
11
|
+
],
|
|
12
|
+
"instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
|
|
13
|
+
}
|
package/examples/example.json
CHANGED
|
@@ -1,37 +1,32 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"defaultModel": "claude-sonnet-4-5",
|
|
33
|
-
"defaultThinkingLevel": "high",
|
|
34
|
-
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
35
|
-
}
|
|
36
|
-
}
|
|
2
|
+
"label": "Implementation",
|
|
3
|
+
"description": "Full-powered implementation profile: every available field, pinned model",
|
|
4
|
+
"skills": [
|
|
5
|
+
"tdd",
|
|
6
|
+
"internal-*",
|
|
7
|
+
"mcp-scripting"
|
|
8
|
+
],
|
|
9
|
+
"extensions": [
|
|
10
|
+
"pi-mcp-adapter"
|
|
11
|
+
],
|
|
12
|
+
"mcps": [
|
|
13
|
+
"github",
|
|
14
|
+
"linear"
|
|
15
|
+
],
|
|
16
|
+
"tools": [
|
|
17
|
+
"read",
|
|
18
|
+
"grep",
|
|
19
|
+
"find",
|
|
20
|
+
"ls",
|
|
21
|
+
"bash",
|
|
22
|
+
"edit",
|
|
23
|
+
"write",
|
|
24
|
+
"mcp__*",
|
|
25
|
+
"github_*",
|
|
26
|
+
"linear_*"
|
|
27
|
+
],
|
|
28
|
+
"defaultProvider": "anthropic",
|
|
29
|
+
"defaultModel": "claude-sonnet-4-5",
|
|
30
|
+
"defaultThinkingLevel": "high",
|
|
31
|
+
"instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
|
|
37
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-profile-switch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Named profiles for Pi: reference skills, extensions, MCP servers, and tools per workflow, switched without restarting. Install: npm install -g pi-profile-switch (not pi install).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -1,86 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"title": "pi-profile-switch profile
|
|
4
|
-
"description": "
|
|
3
|
+
"title": "pi-profile-switch profile definition",
|
|
4
|
+
"description": "A named profile definition stored in ~/.pi-profile-switch/profiles/<name>.json or <project>/.pi/profiles/<name>.json. Definitions are complete and self-contained: there is no inheritance field, and resource references are names/globs, never copies.",
|
|
5
5
|
"type": "object",
|
|
6
|
-
"required": [
|
|
7
|
-
"schemaVersion",
|
|
8
|
-
"profiles"
|
|
9
|
-
],
|
|
10
6
|
"additionalProperties": false,
|
|
11
7
|
"properties": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
8
|
+
"label": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Display label in the selector and /profile list."
|
|
14
11
|
},
|
|
15
|
-
"
|
|
16
|
-
"type": "
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
"description": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"skills": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"type": "string"
|
|
21
19
|
},
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"tools": {
|
|
61
|
-
"type": "array",
|
|
62
|
-
"items": {
|
|
63
|
-
"type": "string"
|
|
64
|
-
},
|
|
65
|
-
"description": "Tool names or globs expanded against Pi's live registry (including extension tools)."
|
|
66
|
-
},
|
|
67
|
-
"defaultProvider": {
|
|
68
|
-
"type": "string",
|
|
69
|
-
"description": "Startup provider for this profile (e.g. \"anthropic\", \"openai\"). Mirrors Pi's settings.defaultProvider."
|
|
70
|
-
},
|
|
71
|
-
"defaultModel": {
|
|
72
|
-
"type": "string",
|
|
73
|
-
"description": "Startup model ID for this profile. Mirrors Pi's settings.defaultModel."
|
|
74
|
-
},
|
|
75
|
-
"defaultThinkingLevel": {
|
|
76
|
-
"type": "string",
|
|
77
|
-
"description": "Startup thinking level for this profile. Mirrors Pi's settings.defaultThinkingLevel."
|
|
78
|
-
},
|
|
79
|
-
"instructions": {
|
|
80
|
-
"type": "string",
|
|
81
|
-
"description": "Appended to Pi's fully built system prompt on every turn."
|
|
82
|
-
}
|
|
83
|
-
}
|
|
20
|
+
"description": "Skill names or globs (e.g. \"review\", \"internal-*\") referencing discovered skills."
|
|
21
|
+
},
|
|
22
|
+
"extensions": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"items": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"description": "Extension names or globs. Package names, source aliases, loose-file stems, glob patterns, or direct file paths, resolved against discovered extensions."
|
|
28
|
+
},
|
|
29
|
+
"mcps": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "string"
|
|
33
|
+
},
|
|
34
|
+
"description": "MCP server names or globs, discovered by pi-mcp-adapter configuration. Connection details stay in adapter-managed config."
|
|
35
|
+
},
|
|
36
|
+
"tools": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"description": "Tool names or globs expanded against Pi's live registry (including extension tools)."
|
|
42
|
+
},
|
|
43
|
+
"defaultProvider": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Startup provider for this profile (e.g. \"anthropic\", \"openai\"). Mirrors Pi's settings.defaultProvider."
|
|
46
|
+
},
|
|
47
|
+
"defaultModel": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Startup model ID for this profile. Mirrors Pi's settings.defaultModel."
|
|
50
|
+
},
|
|
51
|
+
"defaultThinkingLevel": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Startup thinking level for this profile. Mirrors Pi's settings.defaultThinkingLevel."
|
|
54
|
+
},
|
|
55
|
+
"instructions": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "Appended to Pi's fully built system prompt on every turn."
|
|
84
58
|
}
|
|
85
59
|
}
|
|
86
60
|
}
|