@principles/core 1.75.0 → 1.77.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 (76) hide show
  1. package/dist/runtime-v2/__tests__/architecture-regression.test.js +14 -1
  2. package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  3. package/dist/runtime-v2/__tests__/feedback/create-report.test.d.ts +2 -0
  4. package/dist/runtime-v2/__tests__/feedback/create-report.test.d.ts.map +1 -0
  5. package/dist/runtime-v2/__tests__/feedback/create-report.test.js +402 -0
  6. package/dist/runtime-v2/__tests__/feedback/create-report.test.js.map +1 -0
  7. package/dist/runtime-v2/__tests__/feedback/privacy-preview.test.d.ts +2 -0
  8. package/dist/runtime-v2/__tests__/feedback/privacy-preview.test.d.ts.map +1 -0
  9. package/dist/runtime-v2/__tests__/feedback/privacy-preview.test.js +128 -0
  10. package/dist/runtime-v2/__tests__/feedback/privacy-preview.test.js.map +1 -0
  11. package/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.d.ts +2 -0
  12. package/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.d.ts.map +1 -0
  13. package/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js +231 -0
  14. package/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js.map +1 -0
  15. package/dist/runtime-v2/__tests__/feedback/render-github-url.test.d.ts +2 -0
  16. package/dist/runtime-v2/__tests__/feedback/render-github-url.test.d.ts.map +1 -0
  17. package/dist/runtime-v2/__tests__/feedback/render-github-url.test.js +102 -0
  18. package/dist/runtime-v2/__tests__/feedback/render-github-url.test.js.map +1 -0
  19. package/dist/runtime-v2/__tests__/feedback/render-markdown.test.d.ts +2 -0
  20. package/dist/runtime-v2/__tests__/feedback/render-markdown.test.d.ts.map +1 -0
  21. package/dist/runtime-v2/__tests__/feedback/render-markdown.test.js +130 -0
  22. package/dist/runtime-v2/__tests__/feedback/render-markdown.test.js.map +1 -0
  23. package/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts +2 -0
  24. package/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts.map +1 -0
  25. package/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js +328 -0
  26. package/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js.map +1 -0
  27. package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +11 -0
  28. package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  29. package/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  30. package/dist/runtime-v2/feature-flags/feature-flag-contract.js +2 -1
  31. package/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  32. package/dist/runtime-v2/feedback/create-report.d.ts +14 -0
  33. package/dist/runtime-v2/feedback/create-report.d.ts.map +1 -0
  34. package/dist/runtime-v2/feedback/create-report.js +257 -0
  35. package/dist/runtime-v2/feedback/create-report.js.map +1 -0
  36. package/dist/runtime-v2/feedback/feedback-types.d.ts +120 -0
  37. package/dist/runtime-v2/feedback/feedback-types.d.ts.map +1 -0
  38. package/dist/runtime-v2/feedback/feedback-types.js +243 -0
  39. package/dist/runtime-v2/feedback/feedback-types.js.map +1 -0
  40. package/dist/runtime-v2/feedback/index.d.ts +9 -0
  41. package/dist/runtime-v2/feedback/index.d.ts.map +1 -0
  42. package/dist/runtime-v2/feedback/index.js +11 -0
  43. package/dist/runtime-v2/feedback/index.js.map +1 -0
  44. package/dist/runtime-v2/feedback/internal-guards.d.ts +2 -0
  45. package/dist/runtime-v2/feedback/internal-guards.d.ts.map +1 -0
  46. package/dist/runtime-v2/feedback/internal-guards.js +6 -0
  47. package/dist/runtime-v2/feedback/internal-guards.js.map +1 -0
  48. package/dist/runtime-v2/feedback/privacy-preview.d.ts +14 -0
  49. package/dist/runtime-v2/feedback/privacy-preview.d.ts.map +1 -0
  50. package/dist/runtime-v2/feedback/privacy-preview.js +128 -0
  51. package/dist/runtime-v2/feedback/privacy-preview.js.map +1 -0
  52. package/dist/runtime-v2/feedback/redact-sensitive.d.ts +37 -0
  53. package/dist/runtime-v2/feedback/redact-sensitive.d.ts.map +1 -0
  54. package/dist/runtime-v2/feedback/redact-sensitive.js +272 -0
  55. package/dist/runtime-v2/feedback/redact-sensitive.js.map +1 -0
  56. package/dist/runtime-v2/feedback/render-github-url.d.ts +21 -0
  57. package/dist/runtime-v2/feedback/render-github-url.d.ts.map +1 -0
  58. package/dist/runtime-v2/feedback/render-github-url.js +57 -0
  59. package/dist/runtime-v2/feedback/render-github-url.js.map +1 -0
  60. package/dist/runtime-v2/feedback/render-markdown.d.ts +12 -0
  61. package/dist/runtime-v2/feedback/render-markdown.d.ts.map +1 -0
  62. package/dist/runtime-v2/feedback/render-markdown.js +166 -0
  63. package/dist/runtime-v2/feedback/render-markdown.js.map +1 -0
  64. package/dist/runtime-v2/feedback/safe-stringify.d.ts +6 -0
  65. package/dist/runtime-v2/feedback/safe-stringify.d.ts.map +1 -0
  66. package/dist/runtime-v2/feedback/safe-stringify.js +115 -0
  67. package/dist/runtime-v2/feedback/safe-stringify.js.map +1 -0
  68. package/dist/runtime-v2/index.d.ts +4 -0
  69. package/dist/runtime-v2/index.d.ts.map +1 -1
  70. package/dist/runtime-v2/index.js +9 -0
  71. package/dist/runtime-v2/index.js.map +1 -1
  72. package/dist/runtime-v2/workspace-guidance-migration.d.ts +12 -0
  73. package/dist/runtime-v2/workspace-guidance-migration.d.ts.map +1 -0
  74. package/dist/runtime-v2/workspace-guidance-migration.js +193 -0
  75. package/dist/runtime-v2/workspace-guidance-migration.js.map +1 -0
  76. package/package.json +5 -1
@@ -0,0 +1,231 @@
1
+ // redact-sensitive.test.ts
2
+ // ERR-001/005: no `as` casts on untrusted input.
3
+ // ERR-002: structured return with reason/nextAction.
4
+ // ERR-003: segment-exact key matching, never substring.
5
+ // ERR-014/016/017: bounded output, BigInt-safe, no throws on non-string.
6
+ import { describe, it, expect } from 'vitest';
7
+ import { redactAbsolutePaths, redactTokenLikeValues, redactEnvLikeValues, redactStackTrace, redactSensitiveFields, REDACTED_PATH, REDACTED_VALUE, } from '../../feedback/redact-sensitive.js';
8
+ describe('redactAbsolutePaths', () => {
9
+ it('replaces Windows-style absolute paths with <redacted-path>', () => {
10
+ const text = 'See C:\\Users\\alice\\project\\file.ts for details';
11
+ const result = redactAbsolutePaths(text);
12
+ expect(result).toContain(REDACTED_PATH);
13
+ expect(result).not.toContain('C:\\Users\\alice');
14
+ });
15
+ it('replaces POSIX absolute paths with <redacted-path>', () => {
16
+ const text = 'Config at /home/alice/.config/app/settings.json';
17
+ const result = redactAbsolutePaths(text);
18
+ expect(result).toContain(REDACTED_PATH);
19
+ expect(result).not.toContain('/home/alice');
20
+ });
21
+ it('leaves relative paths alone', () => {
22
+ const text = 'Open src/index.ts and ./relative/path.ts please';
23
+ const result = redactAbsolutePaths(text);
24
+ expect(result).toBe(text);
25
+ });
26
+ it('handles multiple absolute paths in one string', () => {
27
+ const text = 'From C:\\a\\b.ts to D:\\c\\d.ts works';
28
+ const result = redactAbsolutePaths(text);
29
+ const matches = result.match(new RegExp(REDACTED_PATH.replace(/[<>]/g, '\\$&'), 'g'));
30
+ expect(matches?.length ?? 0).toBeGreaterThanOrEqual(2);
31
+ });
32
+ });
33
+ describe('redactTokenLikeValues', () => {
34
+ it('redacts OpenAI-style sk- tokens', () => {
35
+ const text = 'My key is sk-abcdefghijklmnopqrstuvwxyz0123456789ABCDEF and it works';
36
+ const result = redactTokenLikeValues(text);
37
+ expect(result).toContain(REDACTED_VALUE);
38
+ expect(result).not.toContain('sk-abcdefghijklmnopqrstuvwxyz');
39
+ });
40
+ it('redacts GitHub-style ghp_ tokens', () => {
41
+ const text = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyzABCD';
42
+ const result = redactTokenLikeValues(text);
43
+ expect(result).toContain(REDACTED_VALUE);
44
+ expect(result).not.toContain('ghp_1234567890');
45
+ });
46
+ it('redacts "Bearer xxx" headers', () => {
47
+ const text = 'Authorization: Bearer abc123.def456.ghi789';
48
+ const result = redactTokenLikeValues(text);
49
+ expect(result).toContain(REDACTED_VALUE);
50
+ expect(result).not.toContain('abc123.def456.ghi789');
51
+ });
52
+ it('redacts api_key= and token= style assignments', () => {
53
+ const text = 'config: api_key=mysecretvalue and token=othertokenvalue';
54
+ const result = redactTokenLikeValues(text);
55
+ expect(result).toContain(REDACTED_VALUE);
56
+ expect(result).not.toContain('mysecretvalue');
57
+ expect(result).not.toContain('othertokenvalue');
58
+ });
59
+ it('leaves normal text alone', () => {
60
+ const text = 'This is a normal sentence with no tokens inside.';
61
+ const result = redactTokenLikeValues(text);
62
+ expect(result).toBe(text);
63
+ });
64
+ });
65
+ describe('redactEnvLikeValues', () => {
66
+ it('redacts KEY=value patterns', () => {
67
+ const text = 'Run with API_KEY=verysecretvalue and continue';
68
+ const result = redactEnvLikeValues(text);
69
+ expect(result).toContain(REDACTED_VALUE);
70
+ expect(result).not.toContain('verysecretvalue');
71
+ });
72
+ it('redacts KEY="value" quoted patterns', () => {
73
+ const text = 'export DATABASE_URL="postgres://user:pass@host/db"';
74
+ const result = redactEnvLikeValues(text);
75
+ expect(result).toContain(REDACTED_VALUE);
76
+ expect(result).not.toContain('user:pass@host');
77
+ });
78
+ it('leaves normal text alone', () => {
79
+ const text = 'There is no env var assignment in this sentence.';
80
+ const result = redactEnvLikeValues(text);
81
+ expect(result).toBe(text);
82
+ });
83
+ });
84
+ describe('redactStackTrace', () => {
85
+ it('returns error name + bounded top frame for full stack', () => {
86
+ const text = [
87
+ 'TypeError: cannot read property foo of undefined',
88
+ ' at doWork (C:\\Users\\alice\\project\\src\\a.ts:10:5)',
89
+ ' at callIt (C:\\Users\\alice\\project\\src\\b.ts:25:3)',
90
+ ' at handle (C:\\Users\\alice\\project\\src\\c.ts:99:1)',
91
+ ].join('\n');
92
+ const result = redactStackTrace(text, 1);
93
+ expect(result).toContain('TypeError');
94
+ expect(result).toContain(REDACTED_PATH);
95
+ expect(result).not.toContain('b.ts');
96
+ expect(result).not.toContain('c.ts');
97
+ });
98
+ it('returns "<no-stack>" for empty input', () => {
99
+ expect(redactStackTrace('', 3)).toBe('<no-stack>');
100
+ });
101
+ });
102
+ describe('redactSensitiveFields', () => {
103
+ it('redacts exact sensitive keys (password, token, secret, apiKey, authorization)', () => {
104
+ const input = {
105
+ username: 'alice',
106
+ password: 'supersecret',
107
+ token: 'tok_abc123',
108
+ apiKey: 'ak_live_123',
109
+ authorization: 'Bearer xyz',
110
+ };
111
+ const result = redactSensitiveFields(input);
112
+ expect(result.ok).toBe(true);
113
+ if (!result.ok)
114
+ return;
115
+ const redacted = result.value;
116
+ expect(redacted.username).toBe('alice');
117
+ expect(redacted.password).toBe(REDACTED_VALUE);
118
+ expect(redacted.token).toBe(REDACTED_VALUE);
119
+ expect(redacted.apiKey).toBe(REDACTED_VALUE);
120
+ expect(redacted.authorization).toBe(REDACTED_VALUE);
121
+ expect(result.notes.length).toBeGreaterThan(0);
122
+ });
123
+ it('uses segment-exact key matching (not substring) — "author" should NOT match "auth"', () => {
124
+ const input = { author: 'alice', authenticated: true, authtoken: 'should-redact' };
125
+ const result = redactSensitiveFields(input);
126
+ expect(result.ok).toBe(true);
127
+ if (!result.ok)
128
+ return;
129
+ const redacted = result.value;
130
+ expect(redacted.author).toBe('alice');
131
+ expect(redacted.authenticated).toBe(true);
132
+ // "authtoken" is not a sensitive segment; only exact "authorization" / "auth_token" / "authtoken" forms should match
133
+ // We test that "author" (containing "auth") is NOT redacted (substring pattern is the bug)
134
+ expect(redacted.author).not.toBe(REDACTED_VALUE);
135
+ });
136
+ it('handles circular references without throwing', () => {
137
+ const input = { name: 'root' };
138
+ input.self = input;
139
+ const result = redactSensitiveFields(input);
140
+ expect(result.ok).toBe(true);
141
+ if (!result.ok)
142
+ return;
143
+ const redacted = result.value;
144
+ expect(redacted.name).toBe('root');
145
+ // The circular self-reference should be marked as a redaction note
146
+ expect(result.notes.some((n) => n.includes('circular') || n.includes('cycle'))).toBe(true);
147
+ });
148
+ it('does NOT throw on non-object input — returns structured error', () => {
149
+ const result = redactSensitiveFields(42);
150
+ expect(result.ok).toBe(false);
151
+ if (result.ok)
152
+ return;
153
+ expect(result.error).toBeDefined();
154
+ expect(result.nextAction).toBeDefined();
155
+ });
156
+ it('does NOT throw on null — returns structured error', () => {
157
+ const result = redactSensitiveFields(null);
158
+ expect(result.ok).toBe(false);
159
+ });
160
+ it('handles arrays without throwing', () => {
161
+ const input = [{ password: 'secret1' }, { name: 'safe' }];
162
+ const result = redactSensitiveFields(input);
163
+ expect(result.ok).toBe(true);
164
+ if (!result.ok)
165
+ return;
166
+ const arr = result.value;
167
+ expect(arr[0]?.password).toBe(REDACTED_VALUE);
168
+ expect(arr[1]?.name).toBe('safe');
169
+ });
170
+ it('BigInt values are stringified safely, not thrown', () => {
171
+ const input = { count: BigInt('9999999999999999'), password: 'secret' };
172
+ const result = redactSensitiveFields(input);
173
+ expect(result.ok).toBe(true);
174
+ if (!result.ok)
175
+ return;
176
+ const redacted = result.value;
177
+ expect(redacted.password).toBe(REDACTED_VALUE);
178
+ expect(typeof redacted.count).toBe('string');
179
+ });
180
+ it('records redaction note when string value contains token-like pattern', () => {
181
+ const input = { buildLog: 'Build started. API key sk-ant-1234567890abcdef1234567890 used.' };
182
+ const result = redactSensitiveFields(input);
183
+ expect(result.ok).toBe(true);
184
+ if (!result.ok)
185
+ return;
186
+ const redacted = result.value;
187
+ expect(redacted.buildLog).not.toContain('sk-ant-');
188
+ expect(result.notes.some((n) => n.includes('redacted'))).toBe(true);
189
+ });
190
+ it('records redaction note when string value contains absolute path', () => {
191
+ const input = { cwd: 'Working in C:\\Users\\alice\\secret-project\\src' };
192
+ const result = redactSensitiveFields(input);
193
+ expect(result.ok).toBe(true);
194
+ if (!result.ok)
195
+ return;
196
+ const redacted = result.value;
197
+ expect(redacted.cwd).not.toContain('alice');
198
+ expect(result.notes.some((n) => n.includes('redacted'))).toBe(true);
199
+ });
200
+ it('records redaction note when string value is truncated', () => {
201
+ const longValue = 'x'.repeat(3000);
202
+ const input = { bigField: longValue };
203
+ const result = redactSensitiveFields(input);
204
+ expect(result.ok).toBe(true);
205
+ if (!result.ok)
206
+ return;
207
+ const redacted = result.value;
208
+ expect(redacted.bigField.length).toBeLessThan(longValue.length);
209
+ expect(result.notes.some((n) => n.includes('truncated'))).toBe(true);
210
+ });
211
+ it('records redaction note when string value contains env-like assignment', () => {
212
+ const input = { envDump: 'DATABASE_URL=postgres://user:pass@host:5432/db' };
213
+ const result = redactSensitiveFields(input);
214
+ expect(result.ok).toBe(true);
215
+ if (!result.ok)
216
+ return;
217
+ const redacted = result.value;
218
+ expect(redacted.envDump).not.toContain('postgres://user:pass');
219
+ expect(result.notes.some((n) => n.includes('redacted'))).toBe(true);
220
+ });
221
+ it('does NOT record redaction note for clean string values', () => {
222
+ const input = { message: 'hello world', name: 'test' };
223
+ const result = redactSensitiveFields(input);
224
+ expect(result.ok).toBe(true);
225
+ if (!result.ok)
226
+ return;
227
+ expect(result.notes.some((n) => n.includes('string value redacted'))).toBe(false);
228
+ expect(result.notes.some((n) => n.includes('truncated'))).toBe(false);
229
+ });
230
+ });
231
+ //# sourceMappingURL=redact-sensitive.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact-sensitive.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/__tests__/feedback/redact-sensitive.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=render-github-url.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-github-url.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/__tests__/feedback/render-github-url.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
1
+ // render-github-url.test.ts
2
+ // ERR-001/005: no `as FeedbackType` cast; use isFeedbackType validator.
3
+ // ERR-014/016: correct '\n' newlines, bounded body.
4
+ // Redacts title before embedding in URL.
5
+ import { describe, it, expect } from 'vitest';
6
+ import { buildGitHubIssueDraftUrl, MAX_URL_BODY_LENGTH, GITHUB_REPO, } from '../../feedback/render-github-url.js';
7
+ describe('buildGitHubIssueDraftUrl', () => {
8
+ it('returns a valid GitHub issue URL with type prefix in title', () => {
9
+ const result = buildGitHubIssueDraftUrl('Cannot open page', 'bug', 'short summary');
10
+ expect(result.ok).toBe(true);
11
+ if (!result.ok)
12
+ return;
13
+ expect(result.url).toContain(`https://github.com/${GITHUB_REPO}/issues/new`);
14
+ expect(result.url).toContain('title=');
15
+ expect(result.url).toContain('bug');
16
+ expect(result.url).toContain('Cannot%20open%20page');
17
+ });
18
+ it('redacts absolute paths in title before embedding', () => {
19
+ const result = buildGitHubIssueDraftUrl('Error at C:\\Users\\alice\\secret\\path.ts', 'bug', 'short summary');
20
+ expect(result.ok).toBe(true);
21
+ if (!result.ok)
22
+ return;
23
+ // The raw path should NOT be in the URL
24
+ expect(result.url).not.toContain('C%3A%5CUsers%5Calice');
25
+ // The redacted marker should be present
26
+ expect(result.url).toContain('redacted-path');
27
+ });
28
+ it('binds the body to MAX_URL_BODY_LENGTH', () => {
29
+ const longSummary = 'x'.repeat(5000);
30
+ const result = buildGitHubIssueDraftUrl('title', 'bug', longSummary);
31
+ expect(result.ok).toBe(true);
32
+ if (!result.ok)
33
+ return;
34
+ // The body=... portion of the URL must not exceed the bound
35
+ const bodyMatch = /[?&]body=([^&]*)/.exec(result.url);
36
+ expect(bodyMatch).not.toBeNull();
37
+ if (bodyMatch === null)
38
+ return;
39
+ const raw = bodyMatch[1] ?? '';
40
+ const bodyValue = decodeURIComponent(raw);
41
+ expect(bodyValue.length).toBeLessThanOrEqual(MAX_URL_BODY_LENGTH);
42
+ });
43
+ it('preserves \\n newlines in body (encoded as %0A) instead of literal \\n', () => {
44
+ const summary = 'line one\nline two\nline three';
45
+ const result = buildGitHubIssueDraftUrl('title', 'bug', summary);
46
+ expect(result.ok).toBe(true);
47
+ if (!result.ok)
48
+ return;
49
+ // The body must contain %0A (encoded newline), not literal \n chars
50
+ expect(result.url).toContain('%0A');
51
+ expect(result.url).not.toMatch(/(?<!\\)\\\\n/); // no escaped backslash-n
52
+ });
53
+ it('returns structured error for invalid type — does NOT throw or use `as` cast', () => {
54
+ const result = buildGitHubIssueDraftUrl('title', 'not-a-valid-type', 'summary');
55
+ expect(result.ok).toBe(false);
56
+ if (result.ok)
57
+ return;
58
+ expect(result.error).toBeDefined();
59
+ expect(result.nextAction).toBeDefined();
60
+ expect(typeof result.nextAction).toBe('string');
61
+ });
62
+ it('handles empty summary without throwing', () => {
63
+ const result = buildGitHubIssueDraftUrl('title', 'bug', '');
64
+ expect(result.ok).toBe(true);
65
+ if (!result.ok)
66
+ return;
67
+ expect(result.url).toContain('https://github.com/');
68
+ });
69
+ it('redacts env-like values in title (OPENAI_API_KEY=sk-... does not appear in URL)', () => {
70
+ const result = buildGitHubIssueDraftUrl('Crash with OPENAI_API_KEY=sk-abc1234567890123456789abcdef in env', 'bug', 'short summary');
71
+ expect(result.ok).toBe(true);
72
+ if (!result.ok)
73
+ return;
74
+ // The secret value must be redacted; the key name may remain but the token must not
75
+ expect(result.url).not.toContain('sk-abc1234567890123456789abcdef');
76
+ expect(result.url).toContain('%5BREDACTED%5D');
77
+ });
78
+ it('redacts env-like values in body (OPENAI_API_KEY=sk-... does not appear in URL)', () => {
79
+ const result = buildGitHubIssueDraftUrl('title', 'bug', 'details: OPENAI_API_KEY=sk-abc1234567890123456789abcdef leaked');
80
+ expect(result.ok).toBe(true);
81
+ if (!result.ok)
82
+ return;
83
+ // The secret value must be redacted; the key name may remain but the token must not
84
+ expect(result.url).not.toContain('sk-abc1234567890123456789abcdef');
85
+ expect(result.url).toContain('%5BREDACTED%5D');
86
+ });
87
+ it('returns structured error when shortSummary is not a string', () => {
88
+ const nullResult = buildGitHubIssueDraftUrl('title', 'bug', null);
89
+ expect(nullResult.ok).toBe(false);
90
+ if (nullResult.ok)
91
+ return;
92
+ expect(nullResult.error).toBe('shortSummary must be a string');
93
+ expect(nullResult.nextAction).toBe('provide a string value for shortSummary');
94
+ const numResult = buildGitHubIssueDraftUrl('title', 'bug', 42);
95
+ expect(numResult.ok).toBe(false);
96
+ if (numResult.ok)
97
+ return;
98
+ expect(numResult.error).toBe('shortSummary must be a string');
99
+ expect(numResult.nextAction).toBe('provide a string value for shortSummary');
100
+ });
101
+ });
102
+ //# sourceMappingURL=render-github-url.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-github-url.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/__tests__/feedback/render-github-url.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=render-markdown.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-markdown.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/__tests__/feedback/render-markdown.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ // render-markdown.test.ts
2
+ // ERR-014/016/017: bounded output, correct '\n' newlines (not '\\n'), BigInt-safe.
3
+ import { describe, it, expect } from 'vitest';
4
+ import { renderReportMarkdown, MAX_MARKDOWN_LENGTH } from '../../feedback/render-markdown.js';
5
+ function makeReport(overrides = {}) {
6
+ return {
7
+ id: 'fb-test-1',
8
+ createdAt: '2026-06-01T00:00:00.000Z',
9
+ type: 'bug',
10
+ title: 'Cannot open pain page',
11
+ userText: {
12
+ description: 'Clicking the pain link throws TypeError',
13
+ stepsToReproduce: '1. Go to Overview\n2. Click Pain',
14
+ expectedBehavior: 'Page should open',
15
+ actualBehavior: 'Page throws error',
16
+ userSeverity: 'high',
17
+ },
18
+ diagnosticSummary: {
19
+ versions: { '@principles/core': '1.0.0' },
20
+ platform: { os: 'darwin', node: '20.0.0' },
21
+ featureFlags: { 'mvp-core': true },
22
+ canary: { status: 'available', summary: 'healthy' },
23
+ recentEvents: [
24
+ { type: 'pain_signal', at: '2026-06-01T00:00:00.000Z', summary: 'pain detected' },
25
+ ],
26
+ },
27
+ contextRefs: [{ kind: 'page', id: 'overview' }],
28
+ privacy: {
29
+ includedSections: ['versions', 'platform', 'featureFlags', 'canary', 'userText'],
30
+ excludedByDefault: ['rawPrompt', 'rawChat', 'fileContents', 'envVars', 'tokens', 'fullPaths', 'stackTraces'],
31
+ redactionNotes: [],
32
+ },
33
+ outputs: { markdown: '', emailText: '', githubIssueUrl: '' },
34
+ ...overrides,
35
+ };
36
+ }
37
+ describe('renderReportMarkdown', () => {
38
+ it('uses real \\n newlines, not literal \\n', () => {
39
+ const report = makeReport();
40
+ const md = renderReportMarkdown(report);
41
+ // The markdown must contain actual newline characters separating sections
42
+ expect(md.split('\n').length).toBeGreaterThan(5);
43
+ // The rendered output must NOT contain escaped \n (which would render as backslash-n)
44
+ expect(md).not.toMatch(/\\n/);
45
+ });
46
+ it('contains the type, title, and user-entered text', () => {
47
+ const report = makeReport();
48
+ const md = renderReportMarkdown(report);
49
+ expect(md).toContain('bug');
50
+ expect(md).toContain('Cannot open pain page');
51
+ expect(md).toContain('Clicking the pain link throws TypeError');
52
+ });
53
+ it('contains diagnostics sections (versions, platform, canary)', () => {
54
+ const report = makeReport();
55
+ const md = renderReportMarkdown(report);
56
+ expect(md).toContain('versions');
57
+ expect(md).toContain('platform');
58
+ expect(md).toContain('canary');
59
+ });
60
+ it('contains context refs', () => {
61
+ const report = makeReport();
62
+ const md = renderReportMarkdown(report);
63
+ expect(md).toContain('overview');
64
+ });
65
+ it('is bounded to MAX_MARKDOWN_LENGTH characters', () => {
66
+ const hugeSteps = 'step '.repeat(2000);
67
+ const hugeDescription = 'desc '.repeat(2000);
68
+ const report = makeReport({
69
+ userText: {
70
+ description: hugeDescription,
71
+ stepsToReproduce: hugeSteps,
72
+ expectedBehavior: 'x',
73
+ actualBehavior: 'y',
74
+ userSeverity: 'low',
75
+ },
76
+ });
77
+ const md = renderReportMarkdown(report);
78
+ expect(md.length).toBeLessThanOrEqual(MAX_MARKDOWN_LENGTH);
79
+ });
80
+ it('truncates oversized fields and records a redaction note in privacy.redactionNotes', () => {
81
+ const hugeSteps = 'step '.repeat(2000);
82
+ const report = makeReport({
83
+ userText: {
84
+ description: 'short',
85
+ stepsToReproduce: hugeSteps,
86
+ expectedBehavior: 'x',
87
+ actualBehavior: 'y',
88
+ userSeverity: 'low',
89
+ },
90
+ });
91
+ const md = renderReportMarkdown(report);
92
+ expect(md.length).toBeLessThanOrEqual(MAX_MARKDOWN_LENGTH);
93
+ expect(report.privacy.redactionNotes.some((n) => n.includes('truncat') || n.includes('truncated'))).toBe(true);
94
+ });
95
+ it('BigInt values in diagnostics do not throw (ERR-017)', () => {
96
+ const report = makeReport({
97
+ diagnosticSummary: {
98
+ versions: { count: BigInt(9999999999999) },
99
+ platform: { os: 'linux' },
100
+ featureFlags: {},
101
+ canary: { status: 'unavailable', unavailableReason: 'offline' },
102
+ recentEvents: [],
103
+ },
104
+ });
105
+ let thrown = null;
106
+ try {
107
+ const md = renderReportMarkdown(report);
108
+ expect(md).toBeDefined();
109
+ }
110
+ catch (e) {
111
+ thrown = e;
112
+ }
113
+ expect(thrown).toBeNull();
114
+ });
115
+ it('reflects canary unavailable status in output without throwing', () => {
116
+ const report = makeReport({
117
+ diagnosticSummary: {
118
+ versions: {},
119
+ platform: { os: 'linux' },
120
+ featureFlags: {},
121
+ canary: { status: 'unavailable', unavailableReason: 'no network' },
122
+ recentEvents: [],
123
+ },
124
+ });
125
+ const md = renderReportMarkdown(report);
126
+ expect(md).toContain('unavailable');
127
+ expect(md).toContain('no network');
128
+ });
129
+ });
130
+ //# sourceMappingURL=render-markdown.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-markdown.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/__tests__/feedback/render-markdown.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workspace-guidance-migration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-guidance-migration.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/workspace-guidance-migration.test.ts"],"names":[],"mappings":""}