@auxiora/personality 1.0.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.
Files changed (149) hide show
  1. package/LICENSE +191 -0
  2. package/dist/__tests__/builder.test.d.ts +2 -0
  3. package/dist/__tests__/builder.test.d.ts.map +1 -0
  4. package/dist/__tests__/builder.test.js +67 -0
  5. package/dist/__tests__/builder.test.js.map +1 -0
  6. package/dist/__tests__/conversation-builder.test.d.ts +2 -0
  7. package/dist/__tests__/conversation-builder.test.d.ts.map +1 -0
  8. package/dist/__tests__/conversation-builder.test.js +324 -0
  9. package/dist/__tests__/conversation-builder.test.js.map +1 -0
  10. package/dist/__tests__/escalation.test.d.ts +2 -0
  11. package/dist/__tests__/escalation.test.d.ts.map +1 -0
  12. package/dist/__tests__/escalation.test.js +143 -0
  13. package/dist/__tests__/escalation.test.js.map +1 -0
  14. package/dist/__tests__/manager.test.d.ts +2 -0
  15. package/dist/__tests__/manager.test.d.ts.map +1 -0
  16. package/dist/__tests__/manager.test.js +96 -0
  17. package/dist/__tests__/manager.test.js.map +1 -0
  18. package/dist/__tests__/parser.test.d.ts +2 -0
  19. package/dist/__tests__/parser.test.d.ts.map +1 -0
  20. package/dist/__tests__/parser.test.js +89 -0
  21. package/dist/__tests__/parser.test.js.map +1 -0
  22. package/dist/__tests__/security-floor.test.d.ts +2 -0
  23. package/dist/__tests__/security-floor.test.d.ts.map +1 -0
  24. package/dist/__tests__/security-floor.test.js +183 -0
  25. package/dist/__tests__/security-floor.test.js.map +1 -0
  26. package/dist/builder.d.ts +6 -0
  27. package/dist/builder.d.ts.map +1 -0
  28. package/dist/builder.js +65 -0
  29. package/dist/builder.js.map +1 -0
  30. package/dist/conversation-builder.d.ts +30 -0
  31. package/dist/conversation-builder.d.ts.map +1 -0
  32. package/dist/conversation-builder.js +232 -0
  33. package/dist/conversation-builder.js.map +1 -0
  34. package/dist/escalation.d.ts +35 -0
  35. package/dist/escalation.d.ts.map +1 -0
  36. package/dist/escalation.js +134 -0
  37. package/dist/escalation.js.map +1 -0
  38. package/dist/index.d.ts +21 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +20 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/manager.d.ts +28 -0
  43. package/dist/manager.d.ts.map +1 -0
  44. package/dist/manager.js +114 -0
  45. package/dist/manager.js.map +1 -0
  46. package/dist/marketplace/__tests__/scanner.test.d.ts +2 -0
  47. package/dist/marketplace/__tests__/scanner.test.d.ts.map +1 -0
  48. package/dist/marketplace/__tests__/scanner.test.js +134 -0
  49. package/dist/marketplace/__tests__/scanner.test.js.map +1 -0
  50. package/dist/marketplace/__tests__/schema.test.d.ts +2 -0
  51. package/dist/marketplace/__tests__/schema.test.d.ts.map +1 -0
  52. package/dist/marketplace/__tests__/schema.test.js +243 -0
  53. package/dist/marketplace/__tests__/schema.test.js.map +1 -0
  54. package/dist/marketplace/scanner.d.ts +19 -0
  55. package/dist/marketplace/scanner.d.ts.map +1 -0
  56. package/dist/marketplace/scanner.js +62 -0
  57. package/dist/marketplace/scanner.js.map +1 -0
  58. package/dist/marketplace/schema.d.ts +150 -0
  59. package/dist/marketplace/schema.d.ts.map +1 -0
  60. package/dist/marketplace/schema.js +122 -0
  61. package/dist/marketplace/schema.js.map +1 -0
  62. package/dist/modes/__tests__/mode-detector.test.d.ts +2 -0
  63. package/dist/modes/__tests__/mode-detector.test.d.ts.map +1 -0
  64. package/dist/modes/__tests__/mode-detector.test.js +130 -0
  65. package/dist/modes/__tests__/mode-detector.test.js.map +1 -0
  66. package/dist/modes/__tests__/mode-loader.test.d.ts +2 -0
  67. package/dist/modes/__tests__/mode-loader.test.d.ts.map +1 -0
  68. package/dist/modes/__tests__/mode-loader.test.js +91 -0
  69. package/dist/modes/__tests__/mode-loader.test.js.map +1 -0
  70. package/dist/modes/__tests__/prompt-assembler.test.d.ts +2 -0
  71. package/dist/modes/__tests__/prompt-assembler.test.d.ts.map +1 -0
  72. package/dist/modes/__tests__/prompt-assembler.test.js +241 -0
  73. package/dist/modes/__tests__/prompt-assembler.test.js.map +1 -0
  74. package/dist/modes/mode-detector.d.ts +10 -0
  75. package/dist/modes/mode-detector.d.ts.map +1 -0
  76. package/dist/modes/mode-detector.js +70 -0
  77. package/dist/modes/mode-detector.js.map +1 -0
  78. package/dist/modes/mode-loader.d.ts +14 -0
  79. package/dist/modes/mode-loader.d.ts.map +1 -0
  80. package/dist/modes/mode-loader.js +94 -0
  81. package/dist/modes/mode-loader.js.map +1 -0
  82. package/dist/modes/prompt-assembler.d.ts +27 -0
  83. package/dist/modes/prompt-assembler.d.ts.map +1 -0
  84. package/dist/modes/prompt-assembler.js +224 -0
  85. package/dist/modes/prompt-assembler.js.map +1 -0
  86. package/dist/modes/types.d.ts +42 -0
  87. package/dist/modes/types.d.ts.map +1 -0
  88. package/dist/modes/types.js +24 -0
  89. package/dist/modes/types.js.map +1 -0
  90. package/dist/parser.d.ts +6 -0
  91. package/dist/parser.d.ts.map +1 -0
  92. package/dist/parser.js +122 -0
  93. package/dist/parser.js.map +1 -0
  94. package/dist/security-floor.d.ts +31 -0
  95. package/dist/security-floor.d.ts.map +1 -0
  96. package/dist/security-floor.js +113 -0
  97. package/dist/security-floor.js.map +1 -0
  98. package/dist/types.d.ts +26 -0
  99. package/dist/types.d.ts.map +1 -0
  100. package/dist/types.js +2 -0
  101. package/dist/types.js.map +1 -0
  102. package/dist/voice-profiles.d.ts +23 -0
  103. package/dist/voice-profiles.d.ts.map +1 -0
  104. package/dist/voice-profiles.js +72 -0
  105. package/dist/voice-profiles.js.map +1 -0
  106. package/modes/advisor.md +24 -0
  107. package/modes/analyst.md +25 -0
  108. package/modes/companion.md +24 -0
  109. package/modes/legal.md +1188 -0
  110. package/modes/operator.md +24 -0
  111. package/modes/roast.md +24 -0
  112. package/modes/socratic.md +24 -0
  113. package/modes/writer.md +23 -0
  114. package/package.json +27 -0
  115. package/src/__tests__/builder.test.ts +78 -0
  116. package/src/__tests__/conversation-builder.test.ts +386 -0
  117. package/src/__tests__/escalation.test.ts +172 -0
  118. package/src/__tests__/manager.test.ts +141 -0
  119. package/src/__tests__/parser.test.ts +101 -0
  120. package/src/__tests__/security-floor.test.ts +212 -0
  121. package/src/builder.ts +75 -0
  122. package/src/conversation-builder.ts +279 -0
  123. package/src/escalation.ts +162 -0
  124. package/src/index.ts +55 -0
  125. package/src/manager.ts +119 -0
  126. package/src/marketplace/__tests__/scanner.test.ts +159 -0
  127. package/src/marketplace/__tests__/schema.test.ts +269 -0
  128. package/src/marketplace/scanner.ts +85 -0
  129. package/src/marketplace/schema.ts +141 -0
  130. package/src/modes/__tests__/mode-detector.test.ts +149 -0
  131. package/src/modes/__tests__/mode-loader.test.ts +143 -0
  132. package/src/modes/__tests__/prompt-assembler.test.ts +291 -0
  133. package/src/modes/mode-detector.ts +84 -0
  134. package/src/modes/mode-loader.ts +105 -0
  135. package/src/modes/prompt-assembler.ts +278 -0
  136. package/src/modes/types.ts +67 -0
  137. package/src/parser.ts +132 -0
  138. package/src/security-floor.ts +147 -0
  139. package/src/types.ts +27 -0
  140. package/src/voice-profiles.ts +88 -0
  141. package/templates/chill.md +30 -0
  142. package/templates/creative.md +29 -0
  143. package/templates/friendly.md +28 -0
  144. package/templates/mentor.md +31 -0
  145. package/templates/minimal.md +24 -0
  146. package/templates/professional.md +28 -0
  147. package/templates/technical.md +30 -0
  148. package/tsconfig.json +12 -0
  149. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,143 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { EscalationStateMachine, ESCALATION_LEVELS, SEVERITY_LEVELS, RESPONSE_CATEGORIES, ESCALATION_TABLE, } from '../escalation.js';
3
+ describe('Escalation', () => {
4
+ describe('constants', () => {
5
+ it('should have 4 escalation levels', () => {
6
+ expect(ESCALATION_LEVELS).toHaveLength(4);
7
+ expect(ESCALATION_LEVELS).toEqual(['normal', 'caution', 'serious', 'lockdown']);
8
+ });
9
+ it('should have 4 severity levels', () => {
10
+ expect(SEVERITY_LEVELS).toHaveLength(4);
11
+ });
12
+ it('should have 8 response categories', () => {
13
+ expect(RESPONSE_CATEGORIES).toHaveLength(8);
14
+ });
15
+ it('should have escalation table entries for all categories', () => {
16
+ for (const cat of RESPONSE_CATEGORIES) {
17
+ expect(ESCALATION_TABLE[cat]).toBeDefined();
18
+ expect(ESCALATION_TABLE[cat].severity).toBeDefined();
19
+ expect(ESCALATION_TABLE[cat].canonicalPhrase).toBeDefined();
20
+ }
21
+ });
22
+ });
23
+ describe('EscalationStateMachine', () => {
24
+ it('should start at normal level', () => {
25
+ const sm = new EscalationStateMachine();
26
+ expect(sm.getState().level).toBe('normal');
27
+ });
28
+ it('should escalate normal → caution on low severity event', () => {
29
+ const sm = new EscalationStateMachine();
30
+ sm.processEvent('uncertainty');
31
+ expect(sm.getState().level).toBe('caution');
32
+ });
33
+ it('should escalate normal → serious on medium severity event', () => {
34
+ const sm = new EscalationStateMachine();
35
+ sm.processEvent('access_failure');
36
+ expect(sm.getState().level).toBe('serious');
37
+ });
38
+ it('should escalate normal → lockdown on high severity event', () => {
39
+ const sm = new EscalationStateMachine();
40
+ sm.processEvent('destructive_confirmation');
41
+ expect(sm.getState().level).toBe('lockdown');
42
+ });
43
+ it('should escalate normal → lockdown on critical severity event', () => {
44
+ const sm = new EscalationStateMachine();
45
+ sm.processEvent('security_incident');
46
+ expect(sm.getState().level).toBe('lockdown');
47
+ });
48
+ it('should not de-escalate from an event', () => {
49
+ const sm = new EscalationStateMachine();
50
+ sm.processEvent('security_incident'); // → lockdown
51
+ sm.processEvent('uncertainty'); // low → should NOT de-escalate
52
+ expect(sm.getState().level).toBe('lockdown');
53
+ });
54
+ it('should escalate caution → serious on medium event', () => {
55
+ const sm = new EscalationStateMachine();
56
+ sm.processEvent('rate_limit'); // → caution
57
+ sm.processEvent('provider_unavailable'); // → serious
58
+ expect(sm.getState().level).toBe('serious');
59
+ });
60
+ it('should track lastEvent', () => {
61
+ const sm = new EscalationStateMachine();
62
+ sm.processEvent('rate_limit');
63
+ expect(sm.getState().lastEvent).toBe('rate_limit');
64
+ });
65
+ it('should set enteredAt timestamp', () => {
66
+ const sm = new EscalationStateMachine();
67
+ const before = Date.now();
68
+ sm.processEvent('uncertainty');
69
+ const after = Date.now();
70
+ const state = sm.getState();
71
+ expect(state.enteredAt).toBeDefined();
72
+ expect(state.enteredAt).toBeGreaterThanOrEqual(before);
73
+ expect(state.enteredAt).toBeLessThanOrEqual(after);
74
+ });
75
+ });
76
+ describe('resolve', () => {
77
+ it('should resolve lockdown → normal', () => {
78
+ const sm = new EscalationStateMachine();
79
+ sm.processEvent('security_incident');
80
+ sm.resolve();
81
+ expect(sm.getState().level).toBe('normal');
82
+ });
83
+ it('should resolve serious → normal', () => {
84
+ const sm = new EscalationStateMachine();
85
+ sm.processEvent('access_failure');
86
+ sm.resolve();
87
+ expect(sm.getState().level).toBe('normal');
88
+ });
89
+ it('should resolve caution → normal', () => {
90
+ const sm = new EscalationStateMachine();
91
+ sm.processEvent('uncertainty');
92
+ sm.resolve();
93
+ expect(sm.getState().level).toBe('normal');
94
+ });
95
+ it('should remain normal when resolving from normal', () => {
96
+ const sm = new EscalationStateMachine();
97
+ sm.resolve();
98
+ expect(sm.getState().level).toBe('normal');
99
+ });
100
+ });
101
+ describe('dampenTone', () => {
102
+ const baseTone = {
103
+ warmth: 0.8,
104
+ directness: 0.5,
105
+ humor: 0.6,
106
+ formality: 0.3,
107
+ };
108
+ it('should not change tone at normal level', () => {
109
+ const sm = new EscalationStateMachine();
110
+ const result = sm.dampenTone(baseTone);
111
+ expect(result).toEqual(baseTone);
112
+ });
113
+ it('should halve humor at caution level', () => {
114
+ const sm = new EscalationStateMachine();
115
+ sm.processEvent('uncertainty');
116
+ const result = sm.dampenTone(baseTone);
117
+ expect(result.humor).toBe(0.3); // 0.6 * 0.5
118
+ expect(result.warmth).toBe(baseTone.warmth);
119
+ });
120
+ it('should zero humor and raise directness at serious level', () => {
121
+ const sm = new EscalationStateMachine();
122
+ sm.processEvent('access_failure');
123
+ const result = sm.dampenTone(baseTone);
124
+ expect(result.humor).toBe(0);
125
+ expect(result.directness).toBe(0.6); // raised from 0.5
126
+ });
127
+ it('should keep directness if already above 0.6 at serious level', () => {
128
+ const sm = new EscalationStateMachine();
129
+ sm.processEvent('access_failure');
130
+ const result = sm.dampenTone({ ...baseTone, directness: 0.8 });
131
+ expect(result.directness).toBe(0.8);
132
+ });
133
+ it('should apply full security floor at lockdown level', () => {
134
+ const sm = new EscalationStateMachine();
135
+ sm.processEvent('security_incident');
136
+ const result = sm.dampenTone(baseTone);
137
+ expect(result.humor).toBe(0);
138
+ expect(result.directness).toBeGreaterThanOrEqual(0.7);
139
+ expect(result.formality).toBeGreaterThanOrEqual(0.5);
140
+ });
141
+ });
142
+ });
143
+ //# sourceMappingURL=escalation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalation.test.js","sourceRoot":"","sources":["../../src/__tests__/escalation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import * as os from 'node:os';
5
+ import { PersonalityManager } from '../manager.js';
6
+ describe('PersonalityManager', () => {
7
+ let tmpDir;
8
+ let templatesDir;
9
+ let workspaceDir;
10
+ let manager;
11
+ beforeEach(async () => {
12
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'personality-test-'));
13
+ templatesDir = path.join(tmpDir, 'templates');
14
+ workspaceDir = path.join(tmpDir, 'workspace');
15
+ await fs.mkdir(templatesDir, { recursive: true });
16
+ await fs.mkdir(workspaceDir, { recursive: true });
17
+ manager = new PersonalityManager(templatesDir, workspaceDir);
18
+ });
19
+ afterEach(async () => {
20
+ await fs.rm(tmpDir, { recursive: true, force: true });
21
+ });
22
+ it('should list templates from the templates directory', async () => {
23
+ await fs.writeFile(path.join(templatesDir, 'professional.md'), `<!-- name: Professional Assistant\ndescription: A formal assistant\npreview: How may I assist you? -->\n---\nname: Professional\n---\n`);
24
+ await fs.writeFile(path.join(templatesDir, 'friendly.md'), `<!-- name: Friendly Helper\ndescription: A warm helper\npreview: Hey! What can I do for you? -->\n---\nname: Friendly\n---\n`);
25
+ const templates = await manager.listTemplates();
26
+ expect(templates).toHaveLength(2);
27
+ const ids = templates.map((t) => t.id);
28
+ expect(ids).toContain('professional');
29
+ expect(ids).toContain('friendly');
30
+ });
31
+ it('should return empty array when templates directory does not exist', async () => {
32
+ const badManager = new PersonalityManager('/nonexistent', workspaceDir);
33
+ const templates = await badManager.listTemplates();
34
+ expect(templates).toEqual([]);
35
+ });
36
+ it('should get a specific template by ID', async () => {
37
+ await fs.writeFile(path.join(templatesDir, 'sarcastic.md'), `<!-- name: Sarcastic Bot\ndescription: Witty and sarcastic\npreview: Oh, another question. How delightful. -->\n---\nname: Snarky\n---\n`);
38
+ const template = await manager.getTemplate('sarcastic');
39
+ expect(template).toBeDefined();
40
+ expect(template.id).toBe('sarcastic');
41
+ expect(template.name).toBe('Sarcastic Bot');
42
+ expect(template.description).toBe('Witty and sarcastic');
43
+ expect(template.preview).toBe('Oh, another question. How delightful.');
44
+ });
45
+ it('should return undefined for nonexistent template', async () => {
46
+ const template = await manager.getTemplate('nonexistent');
47
+ expect(template).toBeUndefined();
48
+ });
49
+ it('should apply a template to the workspace', async () => {
50
+ const soulContent = `---\nname: TestBot\npronouns: they/them\n---\n`;
51
+ await fs.writeFile(path.join(templatesDir, 'test.md'), `<!-- name: Test\ndescription: Test template\npreview: Hello -->\n${soulContent}`);
52
+ await manager.applyTemplate('test');
53
+ const written = await fs.readFile(path.join(workspaceDir, 'SOUL.md'), 'utf-8');
54
+ // applyTemplate injects a template ID into the frontmatter
55
+ expect(written).toBe(`---\ntemplate: test\nname: TestBot\npronouns: they/them\n---\n`);
56
+ });
57
+ it('should throw when applying nonexistent template', async () => {
58
+ await expect(manager.applyTemplate('nonexistent')).rejects.toThrow('Template not found: nonexistent');
59
+ });
60
+ it('should read current personality from workspace SOUL.md', async () => {
61
+ await fs.writeFile(path.join(workspaceDir, 'SOUL.md'), `---\nname: Current\npronouns: he/him\nerrorStyle: matter_of_fact\ntone:\n warmth: 0.9\n directness: 0.4\n humor: 0.2\n formality: 0.8\n---\n`);
62
+ const personality = await manager.getCurrentPersonality();
63
+ expect(personality).toBeDefined();
64
+ expect(personality.name).toBe('Current');
65
+ expect(personality.pronouns).toBe('he/him');
66
+ expect(personality.tone.warmth).toBe(0.9);
67
+ });
68
+ it('should return undefined when no SOUL.md exists', async () => {
69
+ const personality = await manager.getCurrentPersonality();
70
+ expect(personality).toBeUndefined();
71
+ });
72
+ it('should build a custom personality and write SOUL.md', async () => {
73
+ const config = {
74
+ name: 'Custom',
75
+ pronouns: 'she/her',
76
+ tone: { warmth: 0.7, directness: 0.6, humor: 0.4, formality: 0.5 },
77
+ expertise: ['Python'],
78
+ errorStyle: 'apologetic',
79
+ catchphrases: { greeting: 'Hi!' },
80
+ boundaries: { neverJokeAbout: [], neverAdviseOn: [] },
81
+ };
82
+ const content = await manager.buildCustom(config, '# My Bot');
83
+ expect(content).toContain('name: Custom');
84
+ expect(content).toContain('# My Bot');
85
+ const written = await fs.readFile(path.join(workspaceDir, 'SOUL.md'), 'utf-8');
86
+ expect(written).toBe(content);
87
+ });
88
+ it('should ignore non-.md files in templates directory', async () => {
89
+ await fs.writeFile(path.join(templatesDir, 'readme.txt'), 'not a template');
90
+ await fs.writeFile(path.join(templatesDir, 'valid.md'), `<!-- name: Valid -->\n---\nname: Valid\n---\n`);
91
+ const templates = await manager.listTemplates();
92
+ expect(templates).toHaveLength(1);
93
+ expect(templates[0].id).toBe('valid');
94
+ });
95
+ });
96
+ //# sourceMappingURL=manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.test.js","sourceRoot":"","sources":["../../src/__tests__/manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/parser.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseSoulMd } from '../parser.js';
3
+ describe('parseSoulMd', () => {
4
+ it('should parse a complete SOUL.md with frontmatter', () => {
5
+ const content = `---
6
+ name: Nova
7
+ pronouns: she/her
8
+ errorStyle: self_deprecating
9
+ tone:
10
+ warmth: 0.8
11
+ directness: 0.7
12
+ humor: 0.5
13
+ formality: 0.3
14
+ expertise:
15
+ - TypeScript
16
+ - DevOps
17
+ catchphrases:
18
+ greeting: Hey there!
19
+ farewell: Catch you later!
20
+ boundaries:
21
+ neverJokeAbout:
22
+ - health
23
+ neverAdviseOn:
24
+ - legal
25
+ ---
26
+
27
+ # Nova's Personality
28
+
29
+ She is friendly and approachable.
30
+ `;
31
+ const result = parseSoulMd(content);
32
+ expect(result.name).toBe('Nova');
33
+ expect(result.pronouns).toBe('she/her');
34
+ expect(result.errorStyle).toBe('self_deprecating');
35
+ expect(result.tone.warmth).toBe(0.8);
36
+ expect(result.tone.directness).toBe(0.7);
37
+ expect(result.tone.humor).toBe(0.5);
38
+ expect(result.tone.formality).toBe(0.3);
39
+ expect(result.expertise).toEqual(['TypeScript', 'DevOps']);
40
+ expect(result.catchphrases.greeting).toBe('Hey there!');
41
+ expect(result.catchphrases.farewell).toBe('Catch you later!');
42
+ expect(result.boundaries.neverJokeAbout).toEqual(['health']);
43
+ expect(result.boundaries.neverAdviseOn).toEqual(['legal']);
44
+ });
45
+ it('should handle minimal frontmatter with defaults', () => {
46
+ const content = `---
47
+ name: Bot
48
+ ---
49
+ `;
50
+ const result = parseSoulMd(content);
51
+ expect(result.name).toBe('Bot');
52
+ expect(result.pronouns).toBe('they/them');
53
+ expect(result.tone.warmth).toBe(0.6);
54
+ expect(result.expertise).toEqual([]);
55
+ expect(result.catchphrases).toEqual({});
56
+ expect(result.boundaries.neverJokeAbout).toEqual([]);
57
+ expect(result.boundaries.neverAdviseOn).toEqual([]);
58
+ });
59
+ it('should throw on content without frontmatter', () => {
60
+ expect(() => parseSoulMd('# Just Markdown')).toThrow('Invalid SOUL.md: missing YAML frontmatter');
61
+ });
62
+ it('should parse quoted strings', () => {
63
+ const content = `---
64
+ name: "Assistant: Pro"
65
+ pronouns: 'they/them'
66
+ ---
67
+ `;
68
+ const result = parseSoulMd(content);
69
+ expect(result.name).toBe('Assistant: Pro');
70
+ expect(result.pronouns).toBe('they/them');
71
+ });
72
+ it('should handle boolean and numeric values', () => {
73
+ const content = `---
74
+ name: Test
75
+ tone:
76
+ warmth: 1
77
+ directness: 0
78
+ humor: 0.99
79
+ formality: 0.01
80
+ ---
81
+ `;
82
+ const result = parseSoulMd(content);
83
+ expect(result.tone.warmth).toBe(1);
84
+ expect(result.tone.directness).toBe(0);
85
+ expect(result.tone.humor).toBe(0.99);
86
+ expect(result.tone.formality).toBe(0.01);
87
+ });
88
+ });
89
+ //# sourceMappingURL=parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../../src/__tests__/parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBnB,CAAC;QAEE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,OAAO,GAAG;;;CAGnB,CAAC;QAEE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAClD,2CAA2C,CAC5C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG;;;;CAInB,CAAC;QAEE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,OAAO,GAAG;;;;;;;;CAQnB,CAAC;QAEE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=security-floor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-floor.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/security-floor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { SecurityFloor, SECURITY_TOOL_PATTERNS, SECURITY_MESSAGE_PATTERNS, } from '../security-floor.js';
3
+ describe('SecurityFloor', () => {
4
+ const sf = new SecurityFloor();
5
+ describe('SECURITY_TOOL_PATTERNS', () => {
6
+ it('should contain expected tool patterns', () => {
7
+ expect(SECURITY_TOOL_PATTERNS).toContain('vault_read');
8
+ expect(SECURITY_TOOL_PATTERNS).toContain('vault_write');
9
+ expect(SECURITY_TOOL_PATTERNS).toContain('vault_delete');
10
+ expect(SECURITY_TOOL_PATTERNS).toContain('secret_rotate');
11
+ expect(SECURITY_TOOL_PATTERNS).toContain('credential_');
12
+ expect(SECURITY_TOOL_PATTERNS).toContain('permission_change');
13
+ expect(SECURITY_TOOL_PATTERNS).toContain('policy_update');
14
+ });
15
+ });
16
+ describe('SECURITY_MESSAGE_PATTERNS', () => {
17
+ it('should have 5 patterns', () => {
18
+ expect(SECURITY_MESSAGE_PATTERNS).toHaveLength(5);
19
+ });
20
+ });
21
+ describe('detectSecurityContext', () => {
22
+ it('should detect vault_read tool call', () => {
23
+ const ctx = sf.detectSecurityContext({
24
+ toolCalls: ['vault_read'],
25
+ userMessage: 'read my keys',
26
+ });
27
+ expect(ctx.active).toBe(true);
28
+ expect(ctx.triggeredBy).toBe('tool');
29
+ });
30
+ it('should detect credential_ prefix in tool calls', () => {
31
+ const ctx = sf.detectSecurityContext({
32
+ toolCalls: ['credential_list'],
33
+ userMessage: 'show credentials',
34
+ });
35
+ expect(ctx.active).toBe(true);
36
+ expect(ctx.triggeredBy).toBe('tool');
37
+ });
38
+ it('should detect "delete my" in message', () => {
39
+ const ctx = sf.detectSecurityContext({
40
+ userMessage: 'Please delete my account data',
41
+ });
42
+ expect(ctx.active).toBe(true);
43
+ expect(ctx.triggeredBy).toBe('message_pattern');
44
+ });
45
+ it('should detect "rotate" in message', () => {
46
+ const ctx = sf.detectSecurityContext({
47
+ userMessage: 'I need to rotate my API keys',
48
+ });
49
+ expect(ctx.active).toBe(true);
50
+ expect(ctx.triggeredBy).toBe('message_pattern');
51
+ });
52
+ it('should detect "revoke" in message', () => {
53
+ const ctx = sf.detectSecurityContext({
54
+ userMessage: 'revoke the access token',
55
+ });
56
+ expect(ctx.active).toBe(true);
57
+ expect(ctx.triggeredBy).toBe('message_pattern');
58
+ });
59
+ it('should detect "remove access" in message', () => {
60
+ const ctx = sf.detectSecurityContext({
61
+ userMessage: 'remove access for that user',
62
+ });
63
+ expect(ctx.active).toBe(true);
64
+ });
65
+ it('should detect "change password" in message', () => {
66
+ const ctx = sf.detectSecurityContext({
67
+ userMessage: 'I want to change password',
68
+ });
69
+ expect(ctx.active).toBe(true);
70
+ });
71
+ it('should detect active incident', () => {
72
+ const ctx = sf.detectSecurityContext({
73
+ userMessage: 'what happened?',
74
+ activeIncident: true,
75
+ });
76
+ expect(ctx.active).toBe(true);
77
+ expect(ctx.triggeredBy).toBe('incident');
78
+ expect(ctx.activeRules).toContain('SF-3');
79
+ });
80
+ it('should detect trust flag', () => {
81
+ const ctx = sf.detectSecurityContext({
82
+ userMessage: 'do something',
83
+ trustFlagged: true,
84
+ });
85
+ expect(ctx.active).toBe(true);
86
+ expect(ctx.triggeredBy).toBe('trust_flag');
87
+ expect(ctx.activeRules).toContain('SF-4');
88
+ });
89
+ it('should detect active workflow', () => {
90
+ const ctx = sf.detectSecurityContext({
91
+ userMessage: 'proceed',
92
+ activeWorkflow: 'key-rotation',
93
+ });
94
+ expect(ctx.active).toBe(true);
95
+ expect(ctx.triggeredBy).toBe('workflow');
96
+ });
97
+ it('should return inactive for normal messages', () => {
98
+ const ctx = sf.detectSecurityContext({
99
+ userMessage: 'What is the weather today?',
100
+ });
101
+ expect(ctx.active).toBe(false);
102
+ expect(ctx.activeRules).toHaveLength(0);
103
+ });
104
+ it('should return inactive for normal messages without tool calls', () => {
105
+ const ctx = sf.detectSecurityContext({
106
+ userMessage: 'Help me write a function',
107
+ });
108
+ expect(ctx.active).toBe(false);
109
+ });
110
+ it('should prioritize incident over tool calls', () => {
111
+ const ctx = sf.detectSecurityContext({
112
+ toolCalls: ['vault_read'],
113
+ userMessage: 'check',
114
+ activeIncident: true,
115
+ });
116
+ expect(ctx.triggeredBy).toBe('incident');
117
+ });
118
+ it('should always include SF-5 when active', () => {
119
+ const ctx = sf.detectSecurityContext({
120
+ userMessage: 'rotate my keys',
121
+ });
122
+ expect(ctx.activeRules).toContain('SF-5');
123
+ });
124
+ });
125
+ describe('applyFloor', () => {
126
+ it('should clamp humor to 0', () => {
127
+ const tone = { warmth: 0.8, directness: 0.5, humor: 0.8, formality: 0.3 };
128
+ const clamped = sf.applyFloor(tone);
129
+ expect(clamped.humor).toBe(0);
130
+ });
131
+ it('should raise directness to at least 0.7', () => {
132
+ const tone = { warmth: 0.5, directness: 0.3, humor: 0.5, formality: 0.5 };
133
+ const clamped = sf.applyFloor(tone);
134
+ expect(clamped.directness).toBe(0.7);
135
+ });
136
+ it('should keep directness if already above 0.7', () => {
137
+ const tone = { warmth: 0.5, directness: 0.9, humor: 0.5, formality: 0.5 };
138
+ const clamped = sf.applyFloor(tone);
139
+ expect(clamped.directness).toBe(0.9);
140
+ });
141
+ it('should raise formality to at least 0.5', () => {
142
+ const tone = { warmth: 0.5, directness: 0.5, humor: 0.5, formality: 0.2 };
143
+ const clamped = sf.applyFloor(tone);
144
+ expect(clamped.formality).toBe(0.5);
145
+ });
146
+ it('should preserve warmth', () => {
147
+ const tone = { warmth: 0.9, directness: 0.8, humor: 0.6, formality: 0.7 };
148
+ const clamped = sf.applyFloor(tone);
149
+ expect(clamped.warmth).toBe(0.9);
150
+ });
151
+ });
152
+ describe('getSecurityPromptSection', () => {
153
+ it('should return empty string for inactive context', () => {
154
+ const section = sf.getSecurityPromptSection({
155
+ active: false,
156
+ triggeredBy: 'message_pattern',
157
+ activeRules: [],
158
+ });
159
+ expect(section).toBe('');
160
+ });
161
+ it('should include header and rules for active context', () => {
162
+ const section = sf.getSecurityPromptSection({
163
+ active: true,
164
+ triggeredBy: 'tool',
165
+ activeRules: ['SF-1', 'SF-2', 'SF-5'],
166
+ });
167
+ expect(section).toContain('## Security Floor Active');
168
+ expect(section).toContain('SF-1');
169
+ expect(section).toContain('SF-2');
170
+ expect(section).toContain('SF-5');
171
+ expect(section).toContain('CREDENTIAL_HANDLING');
172
+ });
173
+ it('should include trigger information', () => {
174
+ const section = sf.getSecurityPromptSection({
175
+ active: true,
176
+ triggeredBy: 'incident',
177
+ activeRules: ['SF-3'],
178
+ });
179
+ expect(section).toContain('Triggered by: incident');
180
+ });
181
+ });
182
+ });
183
+ //# sourceMappingURL=security-floor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-floor.test.js","sourceRoot":"","sources":["../../src/__tests__/security-floor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { SoulConfig } from './types.js';
2
+ /**
3
+ * Build a SOUL.md file content string from a SoulConfig.
4
+ */
5
+ export declare function buildSoulMd(config: SoulConfig, bodyMarkdown?: string): string;
6
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa7C;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CA0D7E"}