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
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Usage:
9
9
  * npm run dev-sync (after npm run build)
10
- * npm run full-build && npm run dev-sync
10
+ * npm run dev-build && npm run dev-sync
11
11
  */
12
12
 
13
13
  import fs from "node:fs";
@@ -12,7 +12,12 @@ import path from "node:path";
12
12
  export interface AgentBootConfig {
13
13
  org: string;
14
14
  orgDisplayName?: string;
15
+
16
+ // AB-88: N-tier scope model — nodes replace flat groups/teams
17
+ // Legacy groups/teams still supported for backward compat; converted to nodes internally.
15
18
  groups?: Record<string, GroupConfig>;
19
+ nodes?: Record<string, ScopeNode>;
20
+
16
21
  personas?: {
17
22
  enabled?: string[];
18
23
  customDir?: string;
@@ -24,6 +29,10 @@ export interface AgentBootConfig {
24
29
  instructions?: {
25
30
  enabled?: string[];
26
31
  };
32
+
33
+ // AB-53: Domain layers
34
+ domains?: DomainReference[];
35
+
27
36
  output?: {
28
37
  distPath?: string;
29
38
  provenanceHeaders?: boolean;
@@ -46,6 +55,16 @@ export interface AgentBootConfig {
46
55
  permissions?: { allow?: string[]; deny?: string[] };
47
56
  mcpServers?: Record<string, unknown>;
48
57
  };
58
+
59
+ // AB-62: Three-tier privacy model
60
+ privacy?: PrivacyConfig;
61
+
62
+ // AB-65: Telemetry configuration
63
+ telemetry?: TelemetryConfig;
64
+
65
+ // AB-61: Managed settings (HARD guardrails for MDM)
66
+ managed?: ManagedConfig;
67
+
49
68
  validation?: {
50
69
  secretPatterns?: string[];
51
70
  strictMode?: boolean;
@@ -56,15 +75,238 @@ export interface GroupConfig {
56
75
  teams?: string[];
57
76
  }
58
77
 
78
+ // ---------------------------------------------------------------------------
79
+ // AB-88: N-tier scope model
80
+ // ---------------------------------------------------------------------------
81
+
82
+ /** A node in the scope tree. Replaces flat groups/teams with arbitrary depth. */
83
+ export interface ScopeNode {
84
+ /** Display name for this scope level */
85
+ displayName?: string;
86
+ /** Child nodes (arbitrary depth) */
87
+ children?: Record<string, ScopeNode>;
88
+ /** Personas enabled at this scope (additive to parent) */
89
+ personas?: string[];
90
+ /** Additional traits enabled at this scope */
91
+ traits?: string[];
92
+ /** Override config values at this scope */
93
+ config?: Record<string, unknown>;
94
+ }
95
+
96
+ /**
97
+ * Flatten a nodes tree into scope paths for compilation.
98
+ * Returns array of { path: "platform/api", node } tuples.
99
+ */
100
+ export function flattenNodes(
101
+ nodes: Record<string, ScopeNode>,
102
+ prefix = ""
103
+ ): Array<{ path: string; node: ScopeNode }> {
104
+ const result: Array<{ path: string; node: ScopeNode }> = [];
105
+ for (const [name, node] of Object.entries(nodes)) {
106
+ const nodePath = prefix ? `${prefix}/${name}` : name;
107
+ result.push({ path: nodePath, node });
108
+ if (node.children) {
109
+ result.push(...flattenNodes(node.children, nodePath));
110
+ }
111
+ }
112
+ return result;
113
+ }
114
+
115
+ /**
116
+ * Convert legacy groups/teams config to N-tier nodes.
117
+ * Groups become depth-1 nodes; teams become depth-2 children.
118
+ */
119
+ export function groupsToNodes(groups: Record<string, GroupConfig>): Record<string, ScopeNode> {
120
+ const nodes: Record<string, ScopeNode> = {};
121
+ for (const [groupName, group] of Object.entries(groups)) {
122
+ const children: Record<string, ScopeNode> = {};
123
+ for (const team of group.teams ?? []) {
124
+ children[team] = {};
125
+ }
126
+ const node: ScopeNode = {};
127
+ if (Object.keys(children).length > 0) {
128
+ node.children = children;
129
+ }
130
+ nodes[groupName] = node;
131
+ }
132
+ return nodes;
133
+ }
134
+
135
+ // ---------------------------------------------------------------------------
136
+ // AB-53: Domain layer references
137
+ // ---------------------------------------------------------------------------
138
+
139
+ export type DomainReference = string | { name: string; version?: string; path?: string };
140
+
141
+ export interface DomainManifest {
142
+ name: string;
143
+ version: string;
144
+ description?: string;
145
+ traits?: string[];
146
+ personas?: string[];
147
+ instructions?: string[];
148
+ requires_core_version?: string;
149
+ }
150
+
151
+ // ---------------------------------------------------------------------------
152
+ // AB-62: Privacy model
153
+ // ---------------------------------------------------------------------------
154
+
155
+ export interface PrivacyConfig {
156
+ /** Three-tier model: private (raw prompts never leave machine),
157
+ * privileged (LLM analysis via API, developer approves),
158
+ * organizational (anonymized metrics only). */
159
+ tier?: "private" | "privileged" | "organizational";
160
+ /** Raw prompts are NEVER collected. This is a design invariant. */
161
+ rawPrompts?: false;
162
+ /** Escalation exception for genuinely harmful content (category flag only). */
163
+ escalationEnabled?: boolean;
164
+ }
165
+
166
+ // ---------------------------------------------------------------------------
167
+ // AB-65: Telemetry config
168
+ // ---------------------------------------------------------------------------
169
+
170
+ export interface TelemetryConfig {
171
+ enabled?: boolean;
172
+ /** How to identify developers in telemetry.
173
+ * false = no developer ID, "hashed" = SHA-256 of email, "email" = raw email. */
174
+ includeDevId?: false | "hashed" | "email";
175
+ /** Path to NDJSON log file. Default: ~/.agentboot/telemetry.ndjson */
176
+ logPath?: string;
177
+ /** Never include raw prompt content in telemetry. Design invariant. */
178
+ includeContent?: false;
179
+ }
180
+
181
+ // ---------------------------------------------------------------------------
182
+ // AB-61: Managed settings (MDM distribution)
183
+ // ---------------------------------------------------------------------------
184
+
185
+ export interface ManagedConfig {
186
+ /** Enable managed settings artifact generation */
187
+ enabled?: boolean;
188
+ /** MDM platform target */
189
+ platform?: "jamf" | "intune" | "jumpcloud" | "kandji" | "other";
190
+ /** Custom output path for managed settings */
191
+ outputPath?: string;
192
+ /** HARD guardrails to enforce via managed settings */
193
+ guardrails?: {
194
+ /** Force-install specific plugins */
195
+ forcePlugins?: string[];
196
+ /** Deny these tool patterns */
197
+ denyTools?: string[];
198
+ /** Require audit logging */
199
+ requireAuditLog?: boolean;
200
+ };
201
+ }
202
+
59
203
  export interface PersonaConfig {
60
204
  name: string;
61
205
  description: string;
62
206
  invocation?: string;
63
207
  model?: string;
64
208
  permissionMode?: string;
209
+ maxTurns?: number;
210
+ disallowedTools?: string[];
211
+ tools?: string[];
212
+ effort?: "low" | "medium" | "high" | "max";
213
+ autonomy?: "advisory" | "auto-approve" | "autonomous";
214
+ skills?: string[];
215
+ memory?: "user" | "project" | "local" | null;
216
+ background?: boolean;
217
+ isolation?: "none" | "worktree";
218
+ tokenBudget?: number;
65
219
  traits?: string[];
66
220
  groups?: Record<string, { traits?: string[] }>;
67
221
  teams?: Record<string, { traits?: string[] }>;
222
+ /** Per-persona hook configuration */
223
+ hooks?: Record<string, unknown>;
224
+ /** Per-persona MCP servers */
225
+ mcpServers?: Record<string, unknown>;
226
+ }
227
+
228
+ // ---------------------------------------------------------------------------
229
+ // AB-64: Telemetry event schema
230
+ // ---------------------------------------------------------------------------
231
+
232
+ export interface TelemetryEvent {
233
+ event: "persona_invocation" | "persona_error" | "hook_execution" | "session_summary";
234
+ persona_id: string;
235
+ persona_version?: string;
236
+ model?: string;
237
+ scope?: string;
238
+ input_tokens?: number;
239
+ output_tokens?: number;
240
+ thinking_tokens?: number;
241
+ tool_calls?: number;
242
+ duration_ms?: number;
243
+ cost_usd?: number;
244
+ findings_count?: {
245
+ CRITICAL?: number;
246
+ ERROR?: number;
247
+ WARN?: number;
248
+ INFO?: number;
249
+ };
250
+ suggestions?: number;
251
+ timestamp: string;
252
+ session_id?: string;
253
+ dev_id?: string;
254
+ }
255
+
256
+ // ---------------------------------------------------------------------------
257
+ // AB-57: Plugin manifest
258
+ // ---------------------------------------------------------------------------
259
+
260
+ export interface PluginManifest {
261
+ name: string;
262
+ version: string;
263
+ description: string;
264
+ author: string;
265
+ license: string;
266
+ agentboot_version: string;
267
+ personas: Array<{
268
+ id: string;
269
+ name: string;
270
+ description: string;
271
+ model?: string | undefined;
272
+ agent_path: string;
273
+ skill_path: string;
274
+ }>;
275
+ traits: Array<{
276
+ id: string;
277
+ path: string;
278
+ }>;
279
+ hooks?: Array<{
280
+ event: string;
281
+ path: string;
282
+ }> | undefined;
283
+ rules?: Array<{
284
+ path: string;
285
+ description?: string | undefined;
286
+ }> | undefined;
287
+ }
288
+
289
+ // ---------------------------------------------------------------------------
290
+ // AB-58: Marketplace manifest
291
+ // ---------------------------------------------------------------------------
292
+
293
+ export interface MarketplaceManifest {
294
+ $schema?: string;
295
+ name: string;
296
+ description: string;
297
+ maintainer: string;
298
+ url?: string;
299
+ entries: MarketplaceEntry[];
300
+ }
301
+
302
+ export interface MarketplaceEntry {
303
+ type: "plugin" | "trait" | "domain" | "persona";
304
+ name: string;
305
+ version: string;
306
+ description: string;
307
+ published_at: string;
308
+ sha256?: string;
309
+ path: string;
68
310
  }
69
311
 
70
312
  // ---------------------------------------------------------------------------
@@ -133,5 +375,21 @@ export function loadConfig(configPath: string): AgentBootConfig {
133
375
  }
134
376
  const raw = fs.readFileSync(configPath, "utf-8");
135
377
  const stripped = stripJsoncComments(raw);
136
- return JSON.parse(stripped) as AgentBootConfig;
378
+ const parsed = JSON.parse(stripped);
379
+
380
+ // Minimal runtime validation for critical fields
381
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
382
+ throw new Error("Config must be a JSON object");
383
+ }
384
+ if (typeof parsed.org !== "string" || parsed.org.length === 0) {
385
+ throw new Error('Config requires a non-empty "org" field (string)');
386
+ }
387
+ if (parsed.personas?.enabled !== undefined && !Array.isArray(parsed.personas.enabled)) {
388
+ throw new Error('"personas.enabled" must be an array of strings');
389
+ }
390
+ if (parsed.sync?.targetDir !== undefined && typeof parsed.sync.targetDir !== "string") {
391
+ throw new Error('"sync.targetDir" must be a string');
392
+ }
393
+
394
+ return parsed as AgentBootConfig;
137
395
  }
@@ -8,7 +8,9 @@
8
8
  // Frontmatter parsing
9
9
  // ---------------------------------------------------------------------------
10
10
 
11
- const FRONTMATTER_RE = /^---\n([\s\S]+?)\n---/;
11
+ // Matches YAML frontmatter blocks. Uses [\s\S]*? (zero or more) so that
12
+ // empty frontmatter (---\n---) returns an empty Map rather than null.
13
+ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---/;
12
14
 
13
15
  export function parseFrontmatter(content: string): Map<string, string> | null {
14
16
  const match = FRONTMATTER_RE.exec(content);
@@ -110,7 +110,7 @@ function checkPersonaExistence(config: AgentBootConfig, configDir: string): Chec
110
110
 
111
111
  const corePersonasDir = path.join(ROOT, "core", "personas");
112
112
  const extendDir = config.personas?.customDir
113
- ? path.resolve(configDir, config.personas.extend)
113
+ ? path.resolve(configDir, config.personas.customDir)
114
114
  : null;
115
115
 
116
116
  // Collect all available persona directories.
@@ -183,7 +183,7 @@ function checkTraitReferences(config: AgentBootConfig, configDir: string): Check
183
183
  // Scan all persona.config.json files.
184
184
  const personaRoots: string[] = [path.join(ROOT, "core", "personas")];
185
185
  if (config.personas?.customDir) {
186
- const ext = path.resolve(configDir, config.personas.extend);
186
+ const ext = path.resolve(configDir, config.personas.customDir);
187
187
  if (fs.existsSync(ext)) personaRoots.push(ext);
188
188
  }
189
189
 
@@ -243,7 +243,7 @@ function checkSkillFrontmatter(config: AgentBootConfig, configDir: string): Chec
243
243
 
244
244
  const personaRoots: string[] = [path.join(ROOT, "core", "personas")];
245
245
  if (config.personas?.customDir) {
246
- const ext = path.resolve(configDir, config.personas.extend);
246
+ const ext = path.resolve(configDir, config.personas.customDir);
247
247
  if (fs.existsSync(ext)) personaRoots.push(ext);
248
248
  }
249
249
 
@@ -295,9 +295,14 @@ function checkSkillFrontmatter(config: AgentBootConfig, configDir: string): Chec
295
295
  // ---------------------------------------------------------------------------
296
296
 
297
297
  function buildSecretPatterns(config: AgentBootConfig): RegExp[] {
298
- const configPatterns = (config.validation?.secretPatterns ?? []).map(
299
- (p) => new RegExp(p)
300
- );
298
+ const configPatterns: RegExp[] = [];
299
+ for (const p of config.validation?.secretPatterns ?? []) {
300
+ try {
301
+ configPatterns.push(new RegExp(p));
302
+ } catch (e: unknown) {
303
+ console.error(` ⚠ Invalid secretPattern regex "${p}": ${e instanceof Error ? e.message : String(e)} — skipping`);
304
+ }
305
+ }
301
306
  return [...DEFAULT_SECRET_PATTERNS, ...configPatterns];
302
307
  }
303
308
 
@@ -311,7 +316,7 @@ function checkNoSecrets(config: AgentBootConfig, configDir: string): CheckResult
311
316
  ];
312
317
 
313
318
  if (config.personas?.customDir) {
314
- const ext = path.resolve(configDir, config.personas.extend);
319
+ const ext = path.resolve(configDir, config.personas.customDir);
315
320
  if (fs.existsSync(ext)) scanRoots.push(ext);
316
321
  }
317
322
 
@@ -0,0 +1,117 @@
1
+ import {themes as prismThemes} from 'prism-react-renderer';
2
+ import type {Config} from '@docusaurus/types';
3
+ import type * as Preset from '@docusaurus/preset-classic';
4
+
5
+ const config: Config = {
6
+ title: 'AgentBoot',
7
+ tagline: 'Convention over configuration for agentic development teams',
8
+ favicon: 'img/favicon.ico',
9
+
10
+ future: {
11
+ v4: true,
12
+ },
13
+
14
+ url: 'https://agentboot.dev',
15
+ baseUrl: '/',
16
+
17
+ organizationName: 'agentboot-dev',
18
+ projectName: 'agentboot',
19
+ deploymentBranch: 'gh-pages',
20
+ trailingSlash: false,
21
+
22
+ onBrokenLinks: 'warn',
23
+
24
+ i18n: {
25
+ defaultLocale: 'en',
26
+ locales: ['en'],
27
+ },
28
+
29
+ presets: [
30
+ [
31
+ 'classic',
32
+ {
33
+ docs: {
34
+ path: '../docs',
35
+ sidebarPath: './sidebars.ts',
36
+ editUrl: 'https://github.com/agentboot-dev/agentboot/tree/main/',
37
+ // Exclude internal docs from the public site
38
+ exclude: ['internal/**'],
39
+ },
40
+ blog: false, // Disable blog for now
41
+ theme: {
42
+ customCss: './src/css/custom.css',
43
+ },
44
+ } satisfies Preset.Options,
45
+ ],
46
+ ],
47
+
48
+ themeConfig: {
49
+ colorMode: {
50
+ defaultMode: 'light',
51
+ respectPrefersColorScheme: true,
52
+ },
53
+ navbar: {
54
+ title: 'AgentBoot',
55
+ items: [
56
+ {
57
+ type: 'docSidebar',
58
+ sidebarId: 'docsSidebar',
59
+ position: 'left',
60
+ label: 'Docs',
61
+ },
62
+ {
63
+ to: '/docs/roadmap',
64
+ label: 'Roadmap',
65
+ position: 'left',
66
+ },
67
+ {
68
+ href: 'https://github.com/agentboot-dev/agentboot',
69
+ label: 'GitHub',
70
+ position: 'right',
71
+ },
72
+ ],
73
+ },
74
+ footer: {
75
+ style: 'dark',
76
+ links: [
77
+ {
78
+ title: 'Documentation',
79
+ items: [
80
+ { label: 'Getting Started', to: '/docs/getting-started' },
81
+ { label: 'Core Concepts', to: '/docs/concepts' },
82
+ { label: 'CLI Reference', to: '/docs/cli-reference' },
83
+ ],
84
+ },
85
+ {
86
+ title: 'Guides',
87
+ items: [
88
+ { label: 'Extending AgentBoot', to: '/docs/extending' },
89
+ { label: 'Prompt Authoring', to: '/docs/prompt-guide' },
90
+ { label: 'Privacy & Safety', to: '/docs/privacy' },
91
+ ],
92
+ },
93
+ {
94
+ title: 'Community',
95
+ items: [
96
+ {
97
+ label: 'GitHub',
98
+ href: 'https://github.com/agentboot-dev/agentboot',
99
+ },
100
+ {
101
+ label: 'Issues',
102
+ href: 'https://github.com/agentboot-dev/agentboot/issues',
103
+ },
104
+ ],
105
+ },
106
+ ],
107
+ copyright: `Copyright ${new Date().getFullYear()} AgentBoot Contributors. Apache-2.0 License.`,
108
+ },
109
+ prism: {
110
+ theme: prismThemes.github,
111
+ darkTheme: prismThemes.dracula,
112
+ additionalLanguages: ['bash', 'json', 'yaml', 'toml'],
113
+ },
114
+ } satisfies Preset.ThemeConfig,
115
+ };
116
+
117
+ export default config;