agentboot 0.1.0 → 0.2.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 (66) hide show
  1. package/README.md +8 -7
  2. package/agentboot.config.json +4 -1
  3. package/package.json +2 -2
  4. package/scripts/cli.ts +42 -14
  5. package/scripts/compile.ts +30 -7
  6. package/scripts/dev-sync.ts +1 -1
  7. package/scripts/lib/config.ts +17 -1
  8. package/scripts/validate.ts +12 -7
  9. package/.github/ISSUE_TEMPLATE/persona-request.md +0 -62
  10. package/.github/ISSUE_TEMPLATE/quality-feedback.md +0 -67
  11. package/.github/workflows/cla.yml +0 -25
  12. package/.github/workflows/validate.yml +0 -49
  13. package/.idea/agentboot.iml +0 -9
  14. package/.idea/misc.xml +0 -6
  15. package/.idea/modules.xml +0 -8
  16. package/.idea/vcs.xml +0 -6
  17. package/CLAUDE.md +0 -230
  18. package/CONTRIBUTING.md +0 -168
  19. package/PERSONAS.md +0 -156
  20. package/core/instructions/baseline.instructions.md +0 -133
  21. package/core/instructions/security.instructions.md +0 -186
  22. package/core/personas/code-reviewer/SKILL.md +0 -175
  23. package/core/personas/security-reviewer/SKILL.md +0 -233
  24. package/core/personas/test-data-expert/SKILL.md +0 -234
  25. package/core/personas/test-generator/SKILL.md +0 -262
  26. package/core/traits/audit-trail.md +0 -182
  27. package/core/traits/confidence-signaling.md +0 -172
  28. package/core/traits/critical-thinking.md +0 -129
  29. package/core/traits/schema-awareness.md +0 -132
  30. package/core/traits/source-citation.md +0 -174
  31. package/core/traits/structured-output.md +0 -199
  32. package/docs/ci-cd-automation.md +0 -548
  33. package/docs/claude-code-reference/README.md +0 -21
  34. package/docs/claude-code-reference/agentboot-coverage.md +0 -484
  35. package/docs/claude-code-reference/feature-inventory.md +0 -906
  36. package/docs/cli-commands-audit.md +0 -112
  37. package/docs/cli-design.md +0 -924
  38. package/docs/concepts.md +0 -1117
  39. package/docs/config-schema-audit.md +0 -121
  40. package/docs/configuration.md +0 -645
  41. package/docs/delivery-methods.md +0 -758
  42. package/docs/developer-onboarding.md +0 -342
  43. package/docs/extending.md +0 -448
  44. package/docs/getting-started.md +0 -298
  45. package/docs/knowledge-layer.md +0 -464
  46. package/docs/marketplace.md +0 -822
  47. package/docs/org-connection.md +0 -570
  48. package/docs/plans/architecture.md +0 -2429
  49. package/docs/plans/design.md +0 -2018
  50. package/docs/plans/prd.md +0 -1862
  51. package/docs/plans/stack-rank.md +0 -261
  52. package/docs/plans/technical-spec.md +0 -2755
  53. package/docs/privacy-and-safety.md +0 -807
  54. package/docs/prompt-optimization.md +0 -1071
  55. package/docs/test-plan.md +0 -972
  56. package/docs/third-party-ecosystem.md +0 -496
  57. package/domains/compliance-template/README.md +0 -173
  58. package/domains/compliance-template/traits/compliance-aware.md +0 -228
  59. package/examples/enterprise/agentboot.config.json +0 -184
  60. package/examples/minimal/agentboot.config.json +0 -46
  61. package/tests/REGRESSION-PLAN.md +0 -705
  62. package/tests/TEST-PLAN.md +0 -111
  63. package/tests/cli.test.ts +0 -705
  64. package/tests/pipeline.test.ts +0 -608
  65. package/tests/validate.test.ts +0 -278
  66. package/tsconfig.json +0 -62
@@ -1,278 +0,0 @@
1
- /**
2
- * Unit tests for validation logic.
3
- *
4
- * Tests config loading (JSONC stripping), persona existence checks,
5
- * trait reference checks, SKILL.md frontmatter parsing, and secret scanning.
6
- */
7
-
8
- import { describe, it, expect } from "vitest";
9
- import fs from "node:fs";
10
- import path from "node:path";
11
- import { stripJsoncComments } from "../scripts/lib/config.js";
12
- import {
13
- parseFrontmatter,
14
- scanForSecrets,
15
- DEFAULT_SECRET_PATTERNS,
16
- } from "../scripts/lib/frontmatter.js";
17
-
18
- // ---------------------------------------------------------------------------
19
- // JSONC stripping
20
- // ---------------------------------------------------------------------------
21
-
22
- describe("stripJsoncComments", () => {
23
- it("strips single-line comments", () => {
24
- const input = `{
25
- "key": "value" // this is a comment
26
- }`;
27
- const stripped = stripJsoncComments(input);
28
- const parsed = JSON.parse(stripped);
29
- expect(parsed.key).toBe("value");
30
- });
31
-
32
- it("strips full-line comments", () => {
33
- const input = `{
34
- // this line is entirely a comment
35
- "key": "value"
36
- }`;
37
- const stripped = stripJsoncComments(input);
38
- const parsed = JSON.parse(stripped);
39
- expect(parsed.key).toBe("value");
40
- });
41
-
42
- it("preserves // inside string values", () => {
43
- const input = `{
44
- "url": "https://example.com/path"
45
- }`;
46
- const stripped = stripJsoncComments(input);
47
- const parsed = JSON.parse(stripped);
48
- expect(parsed.url).toBe("https://example.com/path");
49
- });
50
-
51
- it("handles escaped quotes in strings", () => {
52
- const input = `{
53
- "msg": "say \\"hello\\"" // comment
54
- }`;
55
- const stripped = stripJsoncComments(input);
56
- const parsed = JSON.parse(stripped);
57
- expect(parsed.msg).toBe('say "hello"');
58
- });
59
-
60
- it("parses real agentboot.config.json", () => {
61
- const configPath = path.join(__dirname, "..", "agentboot.config.json");
62
- const raw = fs.readFileSync(configPath, "utf-8");
63
- const stripped = stripJsoncComments(raw);
64
- const config = JSON.parse(stripped);
65
- expect(config.org).toBe("your-org");
66
- expect(config.personas.enabled).toContain("code-reviewer");
67
- });
68
- });
69
-
70
- // ---------------------------------------------------------------------------
71
- // Frontmatter parsing
72
- // ---------------------------------------------------------------------------
73
-
74
- describe("parseFrontmatter", () => {
75
- it("extracts name and description", () => {
76
- const content = `---
77
- name: code-reviewer
78
- description: Reviews code for bugs
79
- ---
80
-
81
- # Code Reviewer`;
82
-
83
- const fields = parseFrontmatter(content);
84
- expect(fields).not.toBeNull();
85
- expect(fields!.get("name")).toBe("code-reviewer");
86
- expect(fields!.get("description")).toBe("Reviews code for bugs");
87
- });
88
-
89
- it("returns null when no frontmatter block", () => {
90
- const content = `# Just a heading\n\nSome content.`;
91
- expect(parseFrontmatter(content)).toBeNull();
92
- });
93
-
94
- it("handles multi-word values", () => {
95
- const content = `---
96
- name: test-generator
97
- description: Writes unit and integration tests for any codebase
98
- ---`;
99
- const fields = parseFrontmatter(content);
100
- expect(fields!.get("description")).toBe(
101
- "Writes unit and integration tests for any codebase"
102
- );
103
- });
104
-
105
- it("parses all real SKILL.md files", () => {
106
- const personasDir = path.join(__dirname, "..", "core", "personas");
107
- const personas = fs.readdirSync(personasDir).filter((entry) =>
108
- fs.statSync(path.join(personasDir, entry)).isDirectory()
109
- );
110
-
111
- expect(personas.length).toBeGreaterThanOrEqual(4);
112
-
113
- for (const persona of personas) {
114
- const skillPath = path.join(personasDir, persona, "SKILL.md");
115
- expect(fs.existsSync(skillPath), `${persona}/SKILL.md should exist`).toBe(true);
116
-
117
- const content = fs.readFileSync(skillPath, "utf-8");
118
- const fields = parseFrontmatter(content);
119
- expect(fields, `${persona}/SKILL.md should have frontmatter`).not.toBeNull();
120
- expect(fields!.has("name"), `${persona} frontmatter should have name`).toBe(true);
121
- expect(fields!.has("description"), `${persona} frontmatter should have description`).toBe(true);
122
- expect(fields!.get("name"), `${persona} name should not be empty`).not.toBe("");
123
- expect(fields!.get("description"), `${persona} description should not be empty`).not.toBe("");
124
- }
125
- });
126
- });
127
-
128
- // ---------------------------------------------------------------------------
129
- // Secret scanning
130
- // ---------------------------------------------------------------------------
131
-
132
- describe("scanForSecrets", () => {
133
- it("detects password assignments", () => {
134
- const content = `const password = "hunter2";`;
135
- const hits = scanForSecrets(content);
136
- expect(hits.length).toBeGreaterThan(0);
137
- });
138
-
139
- it("detects API keys", () => {
140
- const content = `api_key = "sk-1234567890abcdef"`;
141
- const hits = scanForSecrets(content);
142
- expect(hits.length).toBeGreaterThan(0);
143
- });
144
-
145
- it("detects AWS keys", () => {
146
- const content = `aws_access_key_id = AKIAIOSFODNN7EXAMPLE`;
147
- const hits = scanForSecrets(content);
148
- expect(hits.length).toBeGreaterThan(0);
149
- });
150
-
151
- it("detects private keys", () => {
152
- const content = `-----BEGIN RSA PRIVATE KEY-----\nMIIEpA...`;
153
- const hits = scanForSecrets(content);
154
- expect(hits.length).toBeGreaterThan(0);
155
- });
156
-
157
- it("detects GitHub tokens", () => {
158
- const content = `ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij`;
159
- const hits = scanForSecrets(content);
160
- expect(hits.length).toBeGreaterThan(0);
161
- });
162
-
163
- it("does not flag safe content", () => {
164
- const content = `Use environment variables for credentials.\nNever hardcode passwords.`;
165
- const hits = scanForSecrets(content);
166
- expect(hits.length).toBe(0);
167
- });
168
-
169
- it("does not flag password references in instructions", () => {
170
- // Our security instructions mention passwords conceptually — that's fine
171
- const content = `- Never hardcode (not even for local dev)\n- Flag secrets in wrong places`;
172
- const hits = scanForSecrets(content);
173
- expect(hits.length).toBe(0);
174
- });
175
-
176
- it("scans all real trait and persona files without false positives", () => {
177
- const dirs = [
178
- path.join(__dirname, "..", "core", "traits"),
179
- path.join(__dirname, "..", "core", "personas"),
180
- ];
181
-
182
- for (const dir of dirs) {
183
- if (!fs.existsSync(dir)) continue;
184
- const files = walkDir(dir, [".md", ".json"]);
185
- for (const file of files) {
186
- const content = fs.readFileSync(file, "utf-8");
187
- const hits = scanForSecrets(content);
188
- const relPath = path.relative(path.join(__dirname, ".."), file);
189
- expect(hits, `Secret found in ${relPath} at line ${hits[0]?.line}`).toHaveLength(0);
190
- }
191
- }
192
- });
193
- });
194
-
195
- // ---------------------------------------------------------------------------
196
- // persona.config.json validation
197
- // ---------------------------------------------------------------------------
198
-
199
- describe("persona.config.json", () => {
200
- it("exists for all enabled personas", () => {
201
- const configPath = path.join(__dirname, "..", "agentboot.config.json");
202
- const raw = fs.readFileSync(configPath, "utf-8");
203
- const config = JSON.parse(stripJsoncComments(raw));
204
- const enabled: string[] = config.personas.enabled;
205
-
206
- for (const persona of enabled) {
207
- const pcPath = path.join(__dirname, "..", "core", "personas", persona, "persona.config.json");
208
- expect(fs.existsSync(pcPath), `${persona}/persona.config.json should exist`).toBe(true);
209
- }
210
- });
211
-
212
- it("has required fields (name, description, invocation, traits)", () => {
213
- const personasDir = path.join(__dirname, "..", "core", "personas");
214
- const personas = fs.readdirSync(personasDir).filter((entry) =>
215
- fs.statSync(path.join(personasDir, entry)).isDirectory()
216
- );
217
-
218
- for (const persona of personas) {
219
- const pcPath = path.join(personasDir, persona, "persona.config.json");
220
- if (!fs.existsSync(pcPath)) continue;
221
-
222
- const config = JSON.parse(fs.readFileSync(pcPath, "utf-8"));
223
- expect(config.name, `${persona} should have name`).toBeTruthy();
224
- expect(config.description, `${persona} should have description`).toBeTruthy();
225
- expect(config.invocation, `${persona} should have invocation`).toBeTruthy();
226
- expect(Array.isArray(config.traits), `${persona} traits should be array`).toBe(true);
227
- expect(config.traits.length, `${persona} should have at least one trait`).toBeGreaterThan(0);
228
- }
229
- });
230
-
231
- it("only references traits that exist in core/traits/", () => {
232
- const traitsDir = path.join(__dirname, "..", "core", "traits");
233
- const availableTraits = new Set(
234
- fs.readdirSync(traitsDir)
235
- .filter((f) => f.endsWith(".md"))
236
- .map((f) => path.basename(f, ".md"))
237
- );
238
-
239
- const personasDir = path.join(__dirname, "..", "core", "personas");
240
- const personas = fs.readdirSync(personasDir).filter((entry) =>
241
- fs.statSync(path.join(personasDir, entry)).isDirectory()
242
- );
243
-
244
- for (const persona of personas) {
245
- const pcPath = path.join(personasDir, persona, "persona.config.json");
246
- if (!fs.existsSync(pcPath)) continue;
247
-
248
- const config = JSON.parse(fs.readFileSync(pcPath, "utf-8"));
249
- for (const trait of config.traits ?? []) {
250
- expect(
251
- availableTraits.has(trait),
252
- `${persona} references trait "${trait}" which doesn't exist`
253
- ).toBe(true);
254
- }
255
- }
256
- });
257
- });
258
-
259
- // ---------------------------------------------------------------------------
260
- // Helpers
261
- // ---------------------------------------------------------------------------
262
-
263
- function walkDir(dir: string, extensions: string[]): string[] {
264
- const results: string[] = [];
265
- if (!fs.existsSync(dir)) return results;
266
-
267
- for (const entry of fs.readdirSync(dir)) {
268
- const full = path.join(dir, entry);
269
- const stat = fs.statSync(full);
270
- if (stat.isDirectory()) {
271
- results.push(...walkDir(full, extensions));
272
- } else if (extensions.some((ext) => full.endsWith(ext))) {
273
- results.push(full);
274
- }
275
- }
276
-
277
- return results;
278
- }
package/tsconfig.json DELETED
@@ -1,62 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // ---------------------------------------------------------------------------
4
- // Language and environment
5
- // ---------------------------------------------------------------------------
6
- "target": "ES2022",
7
- "lib": ["ES2022"],
8
- "module": "NodeNext",
9
- "moduleResolution": "NodeNext",
10
-
11
- // ---------------------------------------------------------------------------
12
- // Strict mode — all checks on
13
- // ---------------------------------------------------------------------------
14
- "strict": true,
15
- "noUncheckedIndexedAccess": true, // array[i] is T | undefined
16
- "noImplicitOverride": true, // explicit override keyword required
17
- "noPropertyAccessFromIndexSignature": true,
18
- "exactOptionalPropertyTypes": true, // don't allow undefined where optional
19
-
20
- // ---------------------------------------------------------------------------
21
- // Additional checks
22
- // ---------------------------------------------------------------------------
23
- "noUnusedLocals": true,
24
- "noUnusedParameters": true,
25
- "noFallthroughCasesInSwitch": true,
26
- "noImplicitReturns": true,
27
-
28
- // ---------------------------------------------------------------------------
29
- // Emit
30
- // ---------------------------------------------------------------------------
31
- "outDir": "./dist",
32
- "rootDir": ".",
33
- "declaration": true,
34
- "declarationMap": true,
35
- "sourceMap": true,
36
-
37
- // ---------------------------------------------------------------------------
38
- // Interop
39
- // ---------------------------------------------------------------------------
40
- "esModuleInterop": true,
41
- "allowSyntheticDefaultImports": true,
42
- "resolveJsonModule": true,
43
- "isolatedModules": true,
44
-
45
- // ---------------------------------------------------------------------------
46
- // Path aliases
47
- // ---------------------------------------------------------------------------
48
- "baseUrl": ".",
49
- "paths": {
50
- "@agentboot/*": ["src/*"]
51
- }
52
- },
53
- "include": [
54
- "scripts/**/*.ts",
55
- "src/**/*.ts"
56
- ],
57
- "exclude": [
58
- "node_modules",
59
- "dist",
60
- "**/*.test.ts"
61
- ]
62
- }