@amaster.ai/pi-shared 0.1.2-beta.0 → 0.1.2-beta.2

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=settings.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/settings.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,306 @@
1
+ import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
+ let mockedHome;
6
+ vi.mock('node:os', async (importOriginal) => {
7
+ const actual = await importOriginal();
8
+ return {
9
+ ...actual,
10
+ homedir: () => mockedHome ?? actual.homedir(),
11
+ };
12
+ });
13
+ // Helper to build env-var placeholder strings without triggering biome's noTemplateCurlyInString
14
+ function envRef(expr) {
15
+ // biome-ignore lint/style/useTemplate: intentional concatenation to avoid noTemplateCurlyInString
16
+ return '$' + `{${expr}}`;
17
+ }
18
+ describe('loadPiSettings env var resolution', () => {
19
+ let tempDir;
20
+ let settingsPath;
21
+ let originalCwd;
22
+ let originalEnv;
23
+ beforeEach(() => {
24
+ tempDir = join(tmpdir(), `pi-settings-test-${Date.now()}`);
25
+ mkdirSync(join(tempDir, '.pi'), { recursive: true });
26
+ settingsPath = join(tempDir, '.pi', 'settings.json');
27
+ originalCwd = process.cwd();
28
+ originalEnv = { ...process.env };
29
+ process.chdir(tempDir);
30
+ });
31
+ afterEach(() => {
32
+ process.chdir(originalCwd);
33
+ process.env = originalEnv;
34
+ rmSync(tempDir, { recursive: true, force: true });
35
+ });
36
+ async function loadSettings(key) {
37
+ const mod = await import('../../src/settings.js');
38
+ return mod.loadPiSettings(key);
39
+ }
40
+ it('resolves env ref to env value', async () => {
41
+ process.env.TEST_MODEL = 'claude-opus';
42
+ writeFileSync(settingsPath, JSON.stringify({
43
+ myExt: { name: envRef('TEST_MODEL') },
44
+ }));
45
+ const result = await loadSettings('myExt');
46
+ expect(result.name).toBe('claude-opus');
47
+ });
48
+ it('resolves env ref with default to default when env is unset', async () => {
49
+ delete process.env.UNSET_VAR;
50
+ writeFileSync(settingsPath, JSON.stringify({
51
+ myExt: { name: envRef('UNSET_VAR:-fallback-model') },
52
+ }));
53
+ const result = await loadSettings('myExt');
54
+ expect(result.name).toBe('fallback-model');
55
+ });
56
+ it('resolves env ref with default to env value when set', async () => {
57
+ process.env.SET_VAR = 'actual-value';
58
+ writeFileSync(settingsPath, JSON.stringify({
59
+ myExt: { name: envRef('SET_VAR:-fallback') },
60
+ }));
61
+ const result = await loadSettings('myExt');
62
+ expect(result.name).toBe('actual-value');
63
+ });
64
+ it('resolves env ref with empty default when env is unset', async () => {
65
+ delete process.env.EMPTY_VAR;
66
+ writeFileSync(settingsPath, JSON.stringify({
67
+ myExt: { name: envRef('EMPTY_VAR:-') },
68
+ }));
69
+ const result = await loadSettings('myExt');
70
+ expect(result.name).toBe('');
71
+ });
72
+ it('resolves env ref with empty default when env is empty', async () => {
73
+ process.env.EMPTY_VAR = '';
74
+ writeFileSync(settingsPath, JSON.stringify({
75
+ myExt: { name: envRef('EMPTY_VAR:-') },
76
+ }));
77
+ const result = await loadSettings('myExt');
78
+ expect(result.name).toBe('');
79
+ });
80
+ it('resolves env vars in nested objects', async () => {
81
+ process.env.NESTED_VAL = 'deep';
82
+ writeFileSync(settingsPath, JSON.stringify({
83
+ myExt: { outer: { inner: envRef('NESTED_VAL') } },
84
+ }));
85
+ const result = await loadSettings('myExt');
86
+ expect(result.outer.inner).toBe('deep');
87
+ });
88
+ it('resolves env vars in arrays', async () => {
89
+ process.env.ARR_VAL = 'item1';
90
+ writeFileSync(settingsPath, JSON.stringify({
91
+ myExt: { items: [envRef('ARR_VAL'), 'literal'] },
92
+ }));
93
+ const result = await loadSettings('myExt');
94
+ expect(result.items).toEqual(['item1', 'literal']);
95
+ });
96
+ it('resolves multiple env vars in one string', async () => {
97
+ process.env.HOST = 'localhost';
98
+ process.env.PORT = '8080';
99
+ writeFileSync(settingsPath, JSON.stringify({
100
+ myExt: { url: `http://${envRef('HOST')}:${envRef('PORT')}/api` },
101
+ }));
102
+ const result = await loadSettings('myExt');
103
+ expect(result.url).toBe('http://localhost:8080/api');
104
+ });
105
+ it('leaves non-string values untouched', async () => {
106
+ writeFileSync(settingsPath, JSON.stringify({
107
+ myExt: { count: 42, enabled: true, empty: null },
108
+ }));
109
+ const result = await loadSettings('myExt');
110
+ expect(result.count).toBe(42);
111
+ expect(result.enabled).toBe(true);
112
+ expect(result.empty).toBeNull();
113
+ });
114
+ it('handles default value containing :-', async () => {
115
+ delete process.env.TRICKY_VAR;
116
+ writeFileSync(settingsPath, JSON.stringify({
117
+ myExt: { val: envRef('TRICKY_VAR:-a:-b') },
118
+ }));
119
+ const result = await loadSettings('myExt');
120
+ expect(result.val).toBe('a:-b');
121
+ });
122
+ });
123
+ describe('3-layer settings resolution', () => {
124
+ let base;
125
+ let globalDir;
126
+ let agentDir;
127
+ let projectDir;
128
+ beforeEach(() => {
129
+ base = join(tmpdir(), `pi-3layer-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
130
+ globalDir = join(base, 'home', '.pi', 'agent');
131
+ agentDir = join(base, 'agent-config');
132
+ projectDir = join(base, 'project');
133
+ mkdirSync(globalDir, { recursive: true });
134
+ mkdirSync(agentDir, { recursive: true });
135
+ mkdirSync(join(projectDir, '.pi'), { recursive: true });
136
+ mockedHome = join(base, 'home');
137
+ });
138
+ afterEach(() => {
139
+ mockedHome = undefined;
140
+ rmSync(base, { recursive: true, force: true });
141
+ });
142
+ it('agentDir settings override global settings', async () => {
143
+ writeFileSync(join(globalDir, 'settings.json'), JSON.stringify({ ext: { a: 'global', b: 'global' } }));
144
+ writeFileSync(join(agentDir, 'settings.json'), JSON.stringify({ ext: { a: 'agent' } }));
145
+ const { loadPiSettings } = await import('../../src/settings.js');
146
+ const result = loadPiSettings('ext', {
147
+ agentDir,
148
+ cwd: projectDir,
149
+ });
150
+ expect(result.a).toBe('agent');
151
+ expect(result.b).toBe('global');
152
+ });
153
+ it('project settings override agentDir settings', async () => {
154
+ writeFileSync(join(agentDir, 'settings.json'), JSON.stringify({ ext: { a: 'agent', b: 'agent' } }));
155
+ writeFileSync(join(projectDir, '.pi', 'settings.json'), JSON.stringify({ ext: { a: 'project' } }));
156
+ const { loadPiSettings } = await import('../../src/settings.js');
157
+ const result = loadPiSettings('ext', {
158
+ agentDir,
159
+ cwd: projectDir,
160
+ });
161
+ expect(result.a).toBe('project');
162
+ expect(result.b).toBe('agent');
163
+ });
164
+ it('env var interpolation works in agentDir layer', async () => {
165
+ const origEndpoint = process.env.MY_ENDPOINT;
166
+ process.env.MY_ENDPOINT = 'https://api.example.com';
167
+ writeFileSync(join(agentDir, 'settings.json'), JSON.stringify({ ext: { url: envRef('MY_ENDPOINT') } }));
168
+ const { loadPiSettings } = await import('../../src/settings.js');
169
+ const result = loadPiSettings('ext', { agentDir, cwd: projectDir });
170
+ expect(result.url).toBe('https://api.example.com');
171
+ if (origEndpoint === undefined)
172
+ delete process.env.MY_ENDPOINT;
173
+ else
174
+ process.env.MY_ENDPOINT = origEndpoint;
175
+ });
176
+ it('skips agentDir layer when it equals global dir', async () => {
177
+ writeFileSync(join(globalDir, 'settings.json'), JSON.stringify({ ext: { a: 'global' } }));
178
+ writeFileSync(join(projectDir, '.pi', 'settings.json'), JSON.stringify({ ext: { b: 'project' } }));
179
+ const { loadPiSettings } = await import('../../src/settings.js');
180
+ const result = loadPiSettings('ext', { cwd: projectDir });
181
+ expect(result.a).toBe('global');
182
+ expect(result.b).toBe('project');
183
+ });
184
+ });
185
+ describe('loadPiPolicyProfiles', () => {
186
+ let base;
187
+ let globalPolicyDir;
188
+ let agentDir;
189
+ let agentPolicyDir;
190
+ let projectDir;
191
+ let projectPolicyDir;
192
+ beforeEach(() => {
193
+ base = join(tmpdir(), `pi-policy-3layer-${Date.now()}-${Math.random().toString(36).slice(2)}`);
194
+ globalPolicyDir = join(base, 'home', '.pi', 'agent', 'policy');
195
+ agentDir = join(base, 'agent-config');
196
+ agentPolicyDir = join(agentDir, 'policy');
197
+ projectDir = join(base, 'project');
198
+ projectPolicyDir = join(projectDir, '.pi', 'policy');
199
+ mkdirSync(globalPolicyDir, { recursive: true });
200
+ mkdirSync(agentPolicyDir, { recursive: true });
201
+ mkdirSync(projectPolicyDir, { recursive: true });
202
+ mockedHome = join(base, 'home');
203
+ });
204
+ afterEach(() => {
205
+ mockedHome = undefined;
206
+ rmSync(base, { recursive: true, force: true });
207
+ });
208
+ it('agentDir policy is readable', async () => {
209
+ writeFileSync(join(agentPolicyDir, 'sandbox-exec.json'), JSON.stringify({ extends: 'sandbox-exec', capabilities: { allow: ['browser_*'] } }));
210
+ const { loadPiPolicyProfiles } = await import('../../src/settings.js');
211
+ const result = loadPiPolicyProfiles({
212
+ agentDir,
213
+ cwd: projectDir,
214
+ });
215
+ expect(result['sandbox-exec']).toEqual({
216
+ extends: 'sandbox-exec',
217
+ capabilities: { allow: ['browser_*'] },
218
+ });
219
+ });
220
+ it('project policy overrides agentDir policy with same name', async () => {
221
+ writeFileSync(join(agentPolicyDir, 'custom.json'), JSON.stringify({ extends: 'chat', capabilities: { allow: ['read_file'] } }));
222
+ writeFileSync(join(projectPolicyDir, 'custom.json'), JSON.stringify({ extends: 'copilot', capabilities: { allow: ['*'] } }));
223
+ const { loadPiPolicyProfiles } = await import('../../src/settings.js');
224
+ const result = loadPiPolicyProfiles({
225
+ agentDir,
226
+ cwd: projectDir,
227
+ });
228
+ expect(result.custom).toEqual({ extends: 'copilot', capabilities: { allow: ['*'] } });
229
+ });
230
+ it('merges profiles from all three directories', async () => {
231
+ writeFileSync(join(globalPolicyDir, 'global-only.json'), JSON.stringify({ extends: 'chat' }));
232
+ writeFileSync(join(agentPolicyDir, 'agent-only.json'), JSON.stringify({ extends: 'admin' }));
233
+ writeFileSync(join(projectPolicyDir, 'project-only.json'), JSON.stringify({ extends: 'copilot' }));
234
+ const { loadPiPolicyProfiles } = await import('../../src/settings.js');
235
+ const result = loadPiPolicyProfiles({ agentDir, cwd: projectDir });
236
+ expect(result['global-only']).toEqual({ extends: 'chat' });
237
+ expect(result['agent-only']).toEqual({ extends: 'admin' });
238
+ expect(result['project-only']).toEqual({ extends: 'copilot' });
239
+ });
240
+ it('works when directories do not exist', async () => {
241
+ rmSync(globalPolicyDir, { recursive: true });
242
+ rmSync(agentPolicyDir, { recursive: true });
243
+ rmSync(projectPolicyDir, { recursive: true });
244
+ const { loadPiPolicyProfiles } = await import('../../src/settings.js');
245
+ const result = loadPiPolicyProfiles({ agentDir, cwd: projectDir });
246
+ expect(result).toEqual({});
247
+ });
248
+ });
249
+ describe('loadJsonProfileDir', () => {
250
+ let dir;
251
+ beforeEach(() => {
252
+ dir = join(tmpdir(), `pi-profile-dir-${Date.now()}-${Math.random().toString(36).slice(2)}`);
253
+ mkdirSync(dir, { recursive: true });
254
+ });
255
+ afterEach(() => {
256
+ rmSync(dir, { recursive: true, force: true });
257
+ });
258
+ it('reads all .json files and returns Record keyed by filename', async () => {
259
+ writeFileSync(join(dir, 'alpha.json'), JSON.stringify({ value: 1 }));
260
+ writeFileSync(join(dir, 'beta.json'), JSON.stringify({ value: 2 }));
261
+ const { loadJsonProfileDir } = await import('../../src/settings.js');
262
+ const result = loadJsonProfileDir(dir);
263
+ expect(result).toEqual({ alpha: { value: 1 }, beta: { value: 2 } });
264
+ });
265
+ it('returns empty for non-existent directory', async () => {
266
+ const { loadJsonProfileDir } = await import('../../src/settings.js');
267
+ expect(loadJsonProfileDir('/non/existent/path')).toEqual({});
268
+ });
269
+ it('skips malformed JSON', async () => {
270
+ writeFileSync(join(dir, 'bad.json'), '{ invalid !!!');
271
+ writeFileSync(join(dir, 'good.json'), JSON.stringify({ ok: true }));
272
+ const { loadJsonProfileDir } = await import('../../src/settings.js');
273
+ const result = loadJsonProfileDir(dir);
274
+ expect(result).toEqual({ good: { ok: true } });
275
+ });
276
+ it('skips non-JSON files', async () => {
277
+ writeFileSync(join(dir, 'notes.txt'), 'not json');
278
+ writeFileSync(join(dir, 'valid.json'), JSON.stringify({ x: 1 }));
279
+ const { loadJsonProfileDir } = await import('../../src/settings.js');
280
+ const result = loadJsonProfileDir(dir);
281
+ expect(Object.keys(result)).toEqual(['valid']);
282
+ });
283
+ it('skips non-object JSON values', async () => {
284
+ writeFileSync(join(dir, 'array.json'), JSON.stringify([1, 2]));
285
+ writeFileSync(join(dir, 'str.json'), JSON.stringify('hello'));
286
+ writeFileSync(join(dir, 'obj.json'), JSON.stringify({ ok: true }));
287
+ const { loadJsonProfileDir } = await import('../../src/settings.js');
288
+ const result = loadJsonProfileDir(dir);
289
+ expect(Object.keys(result)).toEqual(['obj']);
290
+ });
291
+ });
292
+ describe('resolveAgentDir', () => {
293
+ it('uses explicit override when provided', async () => {
294
+ const { resolveAgentDir } = await import('../../src/settings.js');
295
+ const result = resolveAgentDir('/explicit/path');
296
+ expect(result).toBe('/explicit/path');
297
+ });
298
+ it('defaults to ~/.pi/agent when no override', async () => {
299
+ const { resolveAgentDir } = await import('../../src/settings.js');
300
+ const os = await import('node:os');
301
+ const path = await import('node:path');
302
+ const result = resolveAgentDir();
303
+ expect(result).toBe(path.resolve(path.join(os.homedir(), '.pi', 'agent')));
304
+ });
305
+ });
306
+ //# sourceMappingURL=settings.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.test.js","sourceRoot":"","sources":["../../src/__tests__/settings.test.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,14 @@
1
+ export type PiSettingsOptions = {
2
+ cwd?: string;
3
+ agentDir?: string;
4
+ };
5
+ export declare function resolveAgentDir(override?: string): string;
1
6
  /**
2
7
  * Load extension config from pi-agent settings files.
3
- * Reads from user (~/.pi/agent/settings.json) and project (<cwd>/.pi/settings.json),
4
- * with project-level fields taking priority.
8
+ * Reads from global (~/.pi/agent/settings.json), agentDir (env/param), and project (<cwd>/.pi/settings.json).
9
+ * Priority from low to high: global < agentDir < project.
5
10
  */
6
- export declare function loadPiSettings<T>(key: string): T;
11
+ export declare function loadPiSettings<T>(key: string, options?: PiSettingsOptions): T;
12
+ export declare function loadJsonProfileDir<T>(dir: string): Record<string, T>;
13
+ export declare function loadPiPolicyProfiles<T>(options?: PiSettingsOptions): Record<string, T>;
7
14
  //# sourceMappingURL=settings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAUhD"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAsCF,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAe7E;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAsBpE;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAWtF"}
package/dist/settings.js CHANGED
@@ -1,12 +1,35 @@
1
- import { readFileSync } from 'node:fs';
1
+ import { readdirSync, readFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
- import { join, resolve } from 'node:path';
3
+ import { basename, join, resolve } from 'node:path';
4
+ function resolveEnvVars(value) {
5
+ if (typeof value === 'string') {
6
+ return value.replace(/\$\{([^}]+)\}/g, (_match, expr) => {
7
+ const [name, ...rest] = expr.split(':-');
8
+ const fallback = rest.join(':-');
9
+ const envVal = process.env[name];
10
+ if (envVal !== undefined && envVal !== '')
11
+ return envVal;
12
+ return fallback;
13
+ });
14
+ }
15
+ if (Array.isArray(value)) {
16
+ return value.map(resolveEnvVars);
17
+ }
18
+ if (value && typeof value === 'object') {
19
+ const result = {};
20
+ for (const [k, v] of Object.entries(value)) {
21
+ result[k] = resolveEnvVars(v);
22
+ }
23
+ return result;
24
+ }
25
+ return value;
26
+ }
4
27
  function readSettingsSection(filePath, key) {
5
28
  try {
6
29
  const raw = readFileSync(filePath, 'utf-8');
7
30
  const parsed = JSON.parse(raw);
8
31
  if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
9
- return (parsed[key] ?? {});
32
+ return resolveEnvVars(parsed[key] ?? {});
10
33
  }
11
34
  return {};
12
35
  }
@@ -14,14 +37,58 @@ function readSettingsSection(filePath, key) {
14
37
  return {};
15
38
  }
16
39
  }
40
+ export function resolveAgentDir(override) {
41
+ return resolve(override ?? join(homedir(), '.pi', 'agent'));
42
+ }
17
43
  /**
18
44
  * Load extension config from pi-agent settings files.
19
- * Reads from user (~/.pi/agent/settings.json) and project (<cwd>/.pi/settings.json),
20
- * with project-level fields taking priority.
45
+ * Reads from global (~/.pi/agent/settings.json), agentDir (env/param), and project (<cwd>/.pi/settings.json).
46
+ * Priority from low to high: global < agentDir < project.
21
47
  */
22
- export function loadPiSettings(key) {
23
- const userSettings = readSettingsSection(join(homedir(), '.pi', 'agent', 'settings.json'), key);
24
- const projectSettings = readSettingsSection(resolve(process.cwd(), '.pi', 'settings.json'), key);
25
- return { ...userSettings, ...projectSettings };
48
+ export function loadPiSettings(key, options) {
49
+ const globalDir = resolve(join(homedir(), '.pi', 'agent'));
50
+ const agentDir = resolveAgentDir(options?.agentDir);
51
+ const cwd = options?.cwd ?? process.cwd();
52
+ const globalSettings = readSettingsSection(join(globalDir, 'settings.json'), key);
53
+ const agentSettings = agentDir === globalDir
54
+ ? {}
55
+ : readSettingsSection(join(agentDir, 'settings.json'), key);
56
+ const projectSettings = readSettingsSection(join(cwd, '.pi', 'settings.json'), key);
57
+ return { ...globalSettings, ...agentSettings, ...projectSettings };
58
+ }
59
+ export function loadJsonProfileDir(dir) {
60
+ const result = {};
61
+ let entries;
62
+ try {
63
+ entries = readdirSync(dir);
64
+ }
65
+ catch {
66
+ return result;
67
+ }
68
+ for (const entry of entries) {
69
+ if (!entry.endsWith('.json'))
70
+ continue;
71
+ const name = basename(entry, '.json');
72
+ try {
73
+ const raw = readFileSync(join(dir, entry), 'utf-8');
74
+ const parsed = JSON.parse(raw);
75
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
76
+ result[name] = parsed;
77
+ }
78
+ }
79
+ catch {
80
+ // skip malformed files
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ export function loadPiPolicyProfiles(options) {
86
+ const globalDir = resolve(join(homedir(), '.pi', 'agent', 'policy'));
87
+ const agentDir = resolve(join(resolveAgentDir(options?.agentDir), 'policy'));
88
+ const projectDir = resolve(join(options?.cwd ?? process.cwd(), '.pi', 'policy'));
89
+ const globalPolicies = loadJsonProfileDir(globalDir);
90
+ const agentPolicies = agentDir === globalDir ? {} : loadJsonProfileDir(agentDir);
91
+ const projectPolicies = loadJsonProfileDir(projectDir);
92
+ return { ...globalPolicies, ...agentPolicies, ...projectPolicies };
26
93
  }
27
94
  //# sourceMappingURL=settings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,SAAS,mBAAmB,CAAI,QAAgB,EAAE,GAAW;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAe,CAAC;QAC3C,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAI,GAAW;IAC3C,MAAM,YAAY,GAAG,mBAAmB,CACtC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,CAAC,EAChD,GAAG,CACJ,CAAC;IACF,MAAM,eAAe,GAAG,mBAAmB,CACzC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,CAAC,EAC9C,GAAG,CACJ,CAAC;IACF,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,eAAe,EAAO,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/pi-shared",
3
- "version": "0.1.2-beta.0",
3
+ "version": "0.1.2-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -30,8 +30,12 @@
30
30
  "url": "https://github.com/TGYD-helige/pi.git",
31
31
  "directory": "packages/shared"
32
32
  },
33
+ "devDependencies": {
34
+ "vitest": "^4.0.0"
35
+ },
33
36
  "scripts": {
34
37
  "build": "tsc -b",
35
- "typecheck": "tsc -b --pretty false"
38
+ "typecheck": "tsc -b --pretty false",
39
+ "test": "vitest run src"
36
40
  }
37
41
  }