agentboot 0.1.0 → 0.3.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 (78) hide show
  1. package/README.md +9 -8
  2. package/agentboot.config.json +4 -1
  3. package/package.json +2 -2
  4. package/scripts/cli.ts +465 -18
  5. package/scripts/compile.ts +724 -75
  6. package/scripts/dev-sync.ts +1 -1
  7. package/scripts/lib/config.ts +259 -1
  8. package/scripts/lib/frontmatter.ts +3 -1
  9. package/scripts/validate.ts +12 -7
  10. package/website/docusaurus.config.ts +117 -0
  11. package/website/package-lock.json +18448 -0
  12. package/website/package.json +47 -0
  13. package/website/sidebars.ts +53 -0
  14. package/website/src/css/custom.css +23 -0
  15. package/website/src/pages/index.module.css +23 -0
  16. package/website/src/pages/index.tsx +125 -0
  17. package/website/static/.nojekyll +0 -0
  18. package/website/static/CNAME +1 -0
  19. package/website/static/img/favicon.ico +0 -0
  20. package/website/static/img/logo.svg +1 -0
  21. package/.github/ISSUE_TEMPLATE/persona-request.md +0 -62
  22. package/.github/ISSUE_TEMPLATE/quality-feedback.md +0 -67
  23. package/.github/workflows/cla.yml +0 -25
  24. package/.github/workflows/validate.yml +0 -49
  25. package/.idea/agentboot.iml +0 -9
  26. package/.idea/misc.xml +0 -6
  27. package/.idea/modules.xml +0 -8
  28. package/.idea/vcs.xml +0 -6
  29. package/CLAUDE.md +0 -230
  30. package/CONTRIBUTING.md +0 -168
  31. package/PERSONAS.md +0 -156
  32. package/core/instructions/baseline.instructions.md +0 -133
  33. package/core/instructions/security.instructions.md +0 -186
  34. package/core/personas/code-reviewer/SKILL.md +0 -175
  35. package/core/personas/security-reviewer/SKILL.md +0 -233
  36. package/core/personas/test-data-expert/SKILL.md +0 -234
  37. package/core/personas/test-generator/SKILL.md +0 -262
  38. package/core/traits/audit-trail.md +0 -182
  39. package/core/traits/confidence-signaling.md +0 -172
  40. package/core/traits/critical-thinking.md +0 -129
  41. package/core/traits/schema-awareness.md +0 -132
  42. package/core/traits/source-citation.md +0 -174
  43. package/core/traits/structured-output.md +0 -199
  44. package/docs/ci-cd-automation.md +0 -548
  45. package/docs/claude-code-reference/README.md +0 -21
  46. package/docs/claude-code-reference/agentboot-coverage.md +0 -484
  47. package/docs/claude-code-reference/feature-inventory.md +0 -906
  48. package/docs/cli-commands-audit.md +0 -112
  49. package/docs/cli-design.md +0 -924
  50. package/docs/concepts.md +0 -1117
  51. package/docs/config-schema-audit.md +0 -121
  52. package/docs/configuration.md +0 -645
  53. package/docs/delivery-methods.md +0 -758
  54. package/docs/developer-onboarding.md +0 -342
  55. package/docs/extending.md +0 -448
  56. package/docs/getting-started.md +0 -298
  57. package/docs/knowledge-layer.md +0 -464
  58. package/docs/marketplace.md +0 -822
  59. package/docs/org-connection.md +0 -570
  60. package/docs/plans/architecture.md +0 -2429
  61. package/docs/plans/design.md +0 -2018
  62. package/docs/plans/prd.md +0 -1862
  63. package/docs/plans/stack-rank.md +0 -261
  64. package/docs/plans/technical-spec.md +0 -2755
  65. package/docs/privacy-and-safety.md +0 -807
  66. package/docs/prompt-optimization.md +0 -1071
  67. package/docs/test-plan.md +0 -972
  68. package/docs/third-party-ecosystem.md +0 -496
  69. package/domains/compliance-template/README.md +0 -173
  70. package/domains/compliance-template/traits/compliance-aware.md +0 -228
  71. package/examples/enterprise/agentboot.config.json +0 -184
  72. package/examples/minimal/agentboot.config.json +0 -46
  73. package/tests/REGRESSION-PLAN.md +0 -705
  74. package/tests/TEST-PLAN.md +0 -111
  75. package/tests/cli.test.ts +0 -705
  76. package/tests/pipeline.test.ts +0 -608
  77. package/tests/validate.test.ts +0 -278
  78. 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
- }