pi-profile-switch 0.7.0 → 0.9.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 CHANGED
@@ -27,72 +27,64 @@ pi-profile ask -- --model openai/gpt-5.4
27
27
 
28
28
  ## Define your own profiles
29
29
 
30
- Profiles live in two JSON files, both optional:
30
+ Profiles live in two directories, with one JSON file per profile:
31
31
 
32
- | File | Scope |
32
+ | Path | Scope |
33
33
  | --- | --- |
34
- | `~/.pi-profile-switch/profiles.json` | Global, all projects. `PI_PROFILE_SWITCH_DIR` overrides the root; `~/.pi/agent/profiles.json` is read as a legacy fallback for migration. |
35
- | `<project>/.pi/profiles.json` | Project-level, trusted projects only. |
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 the JSON directly — schema: [`schemas/profiles.schema.json`](schemas/profiles.schema.json).
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 file with a starter **`ask`** profile — read-only Q&A and code exploration. It assumes nothing about your setup; edit or delete it freely:
39
+ You can also configure profiles conversationally: the package ships a **`profile-config`** skill (distributed to `<agentDir>/skills/profile-config/` on install) that guides the agent to clarify requirements, discover resources, and write or remove profile files. Profiles created with a `skills` list include `"profile-config"` by default (unless explicitly opted out or covered by a wildcard like `"*"`), keeping configuration available after switching. Details: [`skills/profile-config/SKILL.md`](skills/profile-config/SKILL.md).
40
+
41
+ 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
42
 
41
43
  ```json
42
44
  {
43
- "schemaVersion": 1,
44
- "profiles": {
45
- "ask": {
46
- "label": "Ask & Discuss",
47
- "description": "Read-only Q&A and code exploration; no file modifications or command execution",
48
- "skills": [],
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
- }
45
+ "label": "Ask & Discuss",
46
+ "description": "Read-only Q&A and code exploration; no file modifications or command execution",
47
+ "skills": [],
48
+ "extensions": [],
49
+ "tools": ["read", "grep", "find", "ls"],
50
+ "instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
54
51
  }
55
52
  ```
56
53
 
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:
54
+ 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
55
 
59
56
  ```json
60
57
  {
61
- "schemaVersion": 1,
62
- "profiles": {
63
- "impl": {
64
- "label": "Implementation",
65
- "description": "Full-powered implementation profile: every available field, pinned model",
66
- "skills": [
67
- "tdd",
68
- "internal-*",
69
- "mcp-scripting"
70
- ],
71
- "extensions": [
72
- "pi-mcp-adapter"
73
- ],
74
- "mcps": [
75
- "github",
76
- "linear"
77
- ],
78
- "tools": [
79
- "read",
80
- "grep",
81
- "find",
82
- "ls",
83
- "bash",
84
- "edit",
85
- "write",
86
- "mcp__*",
87
- "github_*",
88
- "linear_*"
89
- ],
90
- "defaultProvider": "anthropic",
91
- "defaultModel": "claude-sonnet-4-5",
92
- "defaultThinkingLevel": "high",
93
- "instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
94
- }
95
- }
58
+ "label": "Implementation",
59
+ "description": "Full-powered implementation profile: every available field, pinned model",
60
+ "skills": [
61
+ "tdd",
62
+ "internal-*",
63
+ "mcp-scripting"
64
+ ],
65
+ "extensions": [
66
+ "pi-mcp-adapter"
67
+ ],
68
+ "mcps": [
69
+ "github",
70
+ "linear"
71
+ ],
72
+ "tools": [
73
+ "read",
74
+ "grep",
75
+ "find",
76
+ "ls",
77
+ "bash",
78
+ "edit",
79
+ "write",
80
+ "mcp__*",
81
+ "github_*",
82
+ "linear_*"
83
+ ],
84
+ "defaultProvider": "anthropic",
85
+ "defaultModel": "claude-sonnet-4-5",
86
+ "defaultThinkingLevel": "high",
87
+ "instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
96
88
  }
97
89
  ```
98
90
 
@@ -103,7 +95,15 @@ How fields resolve:
103
95
  - `mcps` references servers from your pi-mcp-adapter configuration; connection details stay in the adapter's own config.
104
96
  - Any field you omit keeps plain Pi behavior.
105
97
 
106
- The files in [`examples/`](examples/) mirror the two profiles above: `profiles.json` is the seeded starter, `example.json` the full-field demo.
98
+ The files in [`examples/`](examples/) mirror the two profiles above: `ask.json` is the seeded starter, `example.json` the full-field demo.
99
+
100
+ ### Migrating from earlier versions
101
+
102
+ 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:
103
+
104
+ 1. Create directory `~/.pi-profile-switch/profiles/` (or `<project>/.pi/profiles/`).
105
+ 2. For each key `<name>` in your old `profiles.json`'s `profiles` object, save its value directly as `<name>.json`.
106
+ 3. Drop the outer `schemaVersion` and `profiles` envelope.
107
107
 
108
108
  ## Commands
109
109
 
package/README.zh-CN.md CHANGED
@@ -27,72 +27,64 @@ pi-profile ask -- --model openai/gpt-5.4
27
27
 
28
28
  ## 自定义 profile
29
29
 
30
- profile 定义在两个 JSON 文件中,均可选:
30
+ profile 保存在两个目录中,每个 profile 对应一个独立 JSON 文件:
31
31
 
32
- | 文件 | 作用域 |
32
+ | 路径 | 作用域 |
33
33
  | --- | --- |
34
- | `~/.pi-profile-switch/profiles.json` | 全局,对所有项目生效。`PI_PROFILE_SWITCH_DIR` 可自定义根目录;`~/.pi/agent/profiles.json` 作为遗留路径向下兼容,用于迁移。 |
35
- | `<项目>/.pi/profiles.json` | 项目级,仅对已信任项目生效。 |
34
+ | `~/.pi-profile-switch/profiles/<name>.json` | 全局,对所有项目生效。`PI_PROFILE_SWITCH_DIR` 可自定义根目录。 |
35
+ | `<项目>/.pi/profiles/<name>.json` | 项目级,仅对已信任项目生效。 |
36
36
 
37
- 直接编辑 JSON 即可创建或修改 profile——schema 见 [`schemas/profiles.schema.json`](schemas/profiles.schema.json)。
37
+ 直接编辑或新建 `<name>.json` 即可创建或修改 profile——schema 见 [`schemas/profiles.schema.json`](schemas/profiles.schema.json)。
38
38
 
39
- 安装时,pi-profile-switch 会向全局文件播种一个初始 **`ask`** profile——只读的问答与代码走读模式。它不假设你安装过任何插件,可随意修改或删除:
39
+ 你也可以通过对话让 agent 帮你配置:随包附带的 **`profile-config`** skill(安装时分发至 `<agentDir>/skills/profile-config/`)会指导 agent 澄清需求、发现资源并读写 profile 文件。按约定,生成声明了 `skills` 的 profile 时默认包含 `"profile-config"`(除非明确排除或已被 `*` 等 glob 覆盖),确保切换到新 profile 后仍可持续对话配置。详情见 [`skills/profile-config/SKILL.md`](skills/profile-config/SKILL.md)。
40
+
41
+ 安装时,pi-profile-switch 会向全局 `profiles/` 目录播种一个初始 **`ask`** profile(`ask.json`)——只读的问答与代码走读模式。它不假设你安装过任何插件,可随意修改或删除:
40
42
 
41
43
  ```json
42
44
  {
43
- "schemaVersion": 1,
44
- "profiles": {
45
- "ask": {
46
- "label": "Ask & Discuss",
47
- "description": "Read-only Q&A and code exploration; no file modifications or command execution",
48
- "skills": [],
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
- }
45
+ "label": "Ask & Discuss",
46
+ "description": "Read-only Q&A and code exploration; no file modifications or command execution",
47
+ "skills": [],
48
+ "extensions": [],
49
+ "tools": ["read", "grep", "find", "ls"],
50
+ "instructions": "You are in read-only discussion mode. Answer questions and explain code without modifying any files or running shell commands."
54
51
  }
55
52
  ```
56
53
 
57
- 一个 profile 可以同时使用全部字段。下面这个 `impl` profile 示例加载 TDD skill、mcp-scripting skill(pi-mcp-adapter 自带)和你的内部 skills;接入两个 MCP server;tool 白名单用 glob 覆盖内建工具和这两个 server 的 MCP 工具;并钉住模型与常驻 instructions:
54
+ 一个 profile 可以同时使用全部字段。下面这个 `impl` profile 示例(`impl.json`)加载 TDD skill、mcp-scripting skill(pi-mcp-adapter 自带)和你的内部 skills;接入两个 MCP server;tool 白名单用 glob 覆盖内建工具和这两个 server 的 MCP 工具;并钉住模型与常驻 instructions:
58
55
 
59
56
  ```json
60
57
  {
61
- "schemaVersion": 1,
62
- "profiles": {
63
- "impl": {
64
- "label": "Implementation",
65
- "description": "Full-powered implementation profile: every available field, pinned model",
66
- "skills": [
67
- "tdd",
68
- "internal-*",
69
- "mcp-scripting"
70
- ],
71
- "extensions": [
72
- "pi-mcp-adapter"
73
- ],
74
- "mcps": [
75
- "github",
76
- "linear"
77
- ],
78
- "tools": [
79
- "read",
80
- "grep",
81
- "find",
82
- "ls",
83
- "bash",
84
- "edit",
85
- "write",
86
- "mcp__*",
87
- "github_*",
88
- "linear_*"
89
- ],
90
- "defaultProvider": "anthropic",
91
- "defaultModel": "claude-sonnet-4-5",
92
- "defaultThinkingLevel": "high",
93
- "instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
94
- }
95
- }
58
+ "label": "Implementation",
59
+ "description": "Full-powered implementation profile: every available field, pinned model",
60
+ "skills": [
61
+ "tdd",
62
+ "internal-*",
63
+ "mcp-scripting"
64
+ ],
65
+ "extensions": [
66
+ "pi-mcp-adapter"
67
+ ],
68
+ "mcps": [
69
+ "github",
70
+ "linear"
71
+ ],
72
+ "tools": [
73
+ "read",
74
+ "grep",
75
+ "find",
76
+ "ls",
77
+ "bash",
78
+ "edit",
79
+ "write",
80
+ "mcp__*",
81
+ "github_*",
82
+ "linear_*"
83
+ ],
84
+ "defaultProvider": "anthropic",
85
+ "defaultModel": "claude-sonnet-4-5",
86
+ "defaultThinkingLevel": "high",
87
+ "instructions": "Prefer small, verifiable changes. Run the test suite before claiming completion."
96
88
  }
97
89
  ```
98
90
 
@@ -103,7 +95,15 @@ profile 定义在两个 JSON 文件中,均可选:
103
95
  - `mcps` 引用 pi-mcp-adapter 配置中的 server;连接细节留在 adapter 自己的配置里。
104
96
  - 未写的字段保持原生 Pi 行为。
105
97
 
106
- [`examples/`](examples/) 中的两个文件与上面一一对应:`profiles.json` 是播种的初始 profile,`example.json` 是全字段演示。
98
+ [`examples/`](examples/) 中的两个文件与上面一一对应:`ask.json` 是播种的初始 profile,`example.json` 是全字段演示。
99
+
100
+ ### 从旧版本迁移
101
+
102
+ 如果你之前使用了把全部 profile 存在单个 `profiles.json`(含 `schemaVersion: 1`)的旧版本,请手动把每个 profile 拆分到 `profiles/` 目录:
103
+
104
+ 1. 创建 `~/.pi-profile-switch/profiles/`(或 `<项目>/.pi/profiles/`)目录。
105
+ 2. 将旧 `profiles.json` 中 `profiles` 下的每个 `<name>` 键值提取为独立的 `<name>.json` 文件。
106
+ 3. 去除外层的 `schemaVersion` 与 `profiles` 信封,文件顶层即为裸 profile 定义。
107
107
 
108
108
  ## 命令
109
109
 
@@ -11,3 +11,5 @@ export interface InstallResult {
11
11
  }
12
12
 
13
13
  export function installDefaultProfiles(options?: { env?: NodeJS.ProcessEnv }): Promise<InstallResult>;
14
+
15
+ export function installProfileConfigSkill(options?: { env?: NodeJS.ProcessEnv }): Promise<InstallResult>;
@@ -1,29 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * postinstall: seed the global catalog with the default profiles file.
3
+ * postinstall: seed the global catalog with the default starter profile,
4
+ * and distribute the profile-config skill to the agent skills directory.
4
5
  *
5
6
  * Runs at package install time (`npm install pi-profile-switch` / `pi install`).
6
7
  * Idempotent and conservative:
7
- * - Writes the shipped `examples/profiles.json` starter catalog to the
8
- * profile-switch dir ONLY when no
9
- * catalog exists there yet (COPYFILE_EXCL; an existing file — including
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).
8
+ * - Writes the shipped `examples/ask.json` starter profile to the
9
+ * profiles dir ONLY when no .json profile exists there yet
10
+ * (COPYFILE_EXCL; an existing file — including one written concurrently — is never touched).
11
+ * - Distributes the shipped `skills/profile-config/SKILL.md` to
12
+ * `<agentDir>/skills/profile-config/SKILL.md`, always overwriting with
13
+ * the shipped version so the skill stays in sync with the package.
14
14
  * - Never fails the install: errors are downgraded to a warning.
15
15
  *
16
16
  * This module is plain Node ESM (no jiti/TS): npm may run postinstall in a
17
17
  * context where only plain JS is safe. The path rules intentionally mirror
18
- * src/workspace.ts — keep them in sync.
18
+ * src/workspace.ts and Pi's getAgentDir() (in @earendil-works/pi-coding-agent)
19
+ * — keep them in sync.
19
20
  */
20
- import { access, copyFile, mkdir } from "node:fs/promises";
21
+ import { copyFile, mkdir, readdir } from "node:fs/promises";
21
22
  import { constants } from "node:fs";
22
23
  import { homedir } from "node:os";
23
24
  import path from "node:path";
24
25
  import { fileURLToPath, pathToFileURL } from "node:url";
25
26
 
26
- const DEFAULT_TEMPLATE = fileURLToPath(new URL("../examples/profiles.json", import.meta.url));
27
+ const DEFAULT_TEMPLATE = fileURLToPath(new URL("../examples/ask.json", import.meta.url));
28
+ const SKILL_TEMPLATE = fileURLToPath(new URL("../skills/profile-config/SKILL.md", import.meta.url));
27
29
 
28
30
  /** Mirrors getProfileSwitchDir() in src/workspace.ts.
29
31
  * @param {NodeJS.ProcessEnv} env */
@@ -33,38 +35,58 @@ function profileSwitchDir(env) {
33
35
  return path.join(homedir(), ".pi-profile-switch");
34
36
  }
35
37
 
36
- /** The legacy migration fallback the resolver still reads (~/.pi/agent).
38
+ /** Mirrors getGlobalProfilesDir() in src/workspace.ts.
37
39
  * @param {NodeJS.ProcessEnv} env */
38
- function legacyCatalogPath(env) {
39
- const agentDir = env.PI_CODING_AGENT_DIR ?? path.join(homedir(), ".pi", "agent");
40
- return path.join(agentDir, "profiles.json");
40
+ function globalProfilesDir(env) {
41
+ return path.join(profileSwitchDir(env), "profiles");
41
42
  }
42
43
 
43
- /** @param {string} filePath */
44
- async function exists(filePath) {
44
+ /** Mirrors Pi's getAgentDir() in @earendil-works/pi-coding-agent.
45
+ * Keep in sync with Pi's config resolution.
46
+ * Deliberate divergence from Pi: trims whitespace and resolves relative
47
+ * paths via path.resolve() for safety during postinstall.
48
+ * @param {NodeJS.ProcessEnv} env */
49
+ function agentDir(env) {
50
+ const override = env.PI_CODING_AGENT_DIR;
51
+ if (override && override.trim()) {
52
+ const trimmed = override.trim();
53
+ if (trimmed === "~") return homedir();
54
+ if (trimmed.startsWith("~/") || (process.platform === "win32" && trimmed.startsWith("~\\"))) {
55
+ return path.join(homedir(), trimmed.slice(2));
56
+ }
57
+ return path.resolve(trimmed);
58
+ }
59
+ return path.join(homedir(), ".pi", "agent");
60
+ }
61
+
62
+ /** Checks whether the directory exists and contains any .json files.
63
+ * @param {string} dir */
64
+ async function hasAnyJsonProfiles(dir) {
45
65
  try {
46
- await access(filePath);
47
- return true;
66
+ const entries = await readdir(dir);
67
+ return entries.some((name) => name.endsWith(".json"));
48
68
  } catch {
49
69
  return false;
50
70
  }
51
71
  }
52
72
 
53
- /** @typedef {{ path: string, written: boolean, skipped?: string }} InstallResult */
73
+ /** @typedef {{ path: string, written: boolean }} InstallResult */
54
74
 
55
75
  /**
56
- * Seeds the default catalog. Safe to call repeatedly; only the first call
57
- * writes.
76
+ * Seeds the default starter profile. Safe to call repeatedly; only writes
77
+ * if no .json files exist in the global profiles directory.
58
78
  * @param {{ env?: NodeJS.ProcessEnv }} [options]
59
79
  * @returns {Promise<InstallResult>}
60
80
  */
61
81
  export async function installDefaultProfiles({ env = process.env } = {}) {
62
- const target = path.join(profileSwitchDir(env), "profiles.json");
63
- if (await exists(target)) return { path: target, written: false };
64
- if (await exists(legacyCatalogPath(env))) {
65
- return { path: target, written: false, skipped: "legacy-catalog-present" };
82
+ const dir = globalProfilesDir(env);
83
+ const target = path.join(dir, "ask.json");
84
+
85
+ if (await hasAnyJsonProfiles(dir)) {
86
+ return { path: target, written: false };
66
87
  }
67
- await mkdir(path.dirname(target), { recursive: true });
88
+
89
+ await mkdir(dir, { recursive: true });
68
90
  try {
69
91
  await copyFile(DEFAULT_TEMPLATE, target, constants.COPYFILE_EXCL);
70
92
  } catch (error) {
@@ -76,14 +98,44 @@ export async function installDefaultProfiles({ env = process.env } = {}) {
76
98
  return { path: target, written: true };
77
99
  }
78
100
 
101
+ /**
102
+ * Distributes the shipped profile-config skill to the agent skills directory.
103
+ * Always overwrites with the shipped version. Downgrades failures to a warning.
104
+ * @param {{ env?: NodeJS.ProcessEnv }} [options]
105
+ * @returns {Promise<InstallResult>}
106
+ */
107
+ export async function installProfileConfigSkill({ env = process.env } = {}) {
108
+ const dir = path.join(agentDir(env), "skills", "profile-config");
109
+ const target = path.join(dir, "SKILL.md");
110
+
111
+ try {
112
+ await mkdir(dir, { recursive: true });
113
+ await copyFile(SKILL_TEMPLATE, target);
114
+ return { path: target, written: true };
115
+ } catch (error) {
116
+ console.warn(
117
+ `pi-profile: could not distribute profile-config skill: ${error instanceof Error ? error.message : error}`,
118
+ );
119
+ return { path: target, written: false };
120
+ }
121
+ }
122
+
79
123
  const invokedDirectly = process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href;
80
124
  if (invokedDirectly) {
81
125
  installDefaultProfiles().then(
82
126
  (result) => {
83
- if (result.written) console.log(`pi-profile: seeded default profiles at ${result.path}`);
127
+ if (result.written) console.log(`pi-profile: seeded starter profile at ${result.path}`);
128
+ },
129
+ (error) => {
130
+ console.warn(`pi-profile: could not seed starter profile: ${error instanceof Error ? error.message : error}`);
131
+ },
132
+ );
133
+ installProfileConfigSkill().then(
134
+ (result) => {
135
+ if (result.written) console.log(`pi-profile: distributed profile-config skill at ${result.path}`);
84
136
  },
85
137
  (error) => {
86
- console.warn(`pi-profile: could not seed default profiles: ${error instanceof Error ? error.message : error}`);
138
+ console.warn(`pi-profile: could not distribute profile-config skill: ${error instanceof Error ? error.message : error}`);
87
139
  },
88
140
  );
89
141
  }
@@ -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
+ }
@@ -1,37 +1,32 @@
1
1
  {
2
- "schemaVersion": 1,
3
- "profiles": {
4
- "impl": {
5
- "label": "Implementation",
6
- "description": "Full-powered implementation profile: every available field, pinned model",
7
- "skills": [
8
- "tdd",
9
- "internal-*",
10
- "mcp-scripting"
11
- ],
12
- "extensions": [
13
- "pi-mcp-adapter"
14
- ],
15
- "mcps": [
16
- "github",
17
- "linear"
18
- ],
19
- "tools": [
20
- "read",
21
- "grep",
22
- "find",
23
- "ls",
24
- "bash",
25
- "edit",
26
- "write",
27
- "mcp__*",
28
- "github_*",
29
- "linear_*"
30
- ],
31
- "defaultProvider": "anthropic",
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.7.0",
3
+ "version": "0.9.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": [
@@ -46,6 +46,7 @@
46
46
  "files": [
47
47
  "bin",
48
48
  "extensions",
49
+ "skills",
49
50
  "src",
50
51
  "schemas",
51
52
  "examples",