agentxchain 0.8.7 → 2.1.1

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 (94) hide show
  1. package/README.md +123 -154
  2. package/bin/agentxchain.js +240 -8
  3. package/dashboard/app.js +305 -0
  4. package/dashboard/components/blocked.js +145 -0
  5. package/dashboard/components/cross-repo.js +126 -0
  6. package/dashboard/components/gate.js +311 -0
  7. package/dashboard/components/hooks.js +177 -0
  8. package/dashboard/components/initiative.js +147 -0
  9. package/dashboard/components/ledger.js +165 -0
  10. package/dashboard/components/timeline.js +222 -0
  11. package/dashboard/index.html +352 -0
  12. package/package.json +16 -7
  13. package/scripts/agentxchain-autonudge.applescript +32 -5
  14. package/scripts/live-api-proxy-preflight-smoke.sh +531 -0
  15. package/scripts/publish-from-tag.sh +88 -0
  16. package/scripts/release-postflight.sh +231 -0
  17. package/scripts/release-preflight.sh +167 -0
  18. package/scripts/run-autonudge.sh +1 -1
  19. package/src/adapters/claude-code.js +7 -14
  20. package/src/adapters/cursor-local.js +17 -16
  21. package/src/commands/accept-turn.js +160 -0
  22. package/src/commands/approve-completion.js +80 -0
  23. package/src/commands/approve-transition.js +85 -0
  24. package/src/commands/branch.js +2 -2
  25. package/src/commands/claim.js +84 -9
  26. package/src/commands/config.js +16 -0
  27. package/src/commands/dashboard.js +70 -0
  28. package/src/commands/doctor.js +9 -1
  29. package/src/commands/init.js +540 -5
  30. package/src/commands/migrate.js +348 -0
  31. package/src/commands/multi.js +549 -0
  32. package/src/commands/plugin.js +157 -0
  33. package/src/commands/reject-turn.js +204 -0
  34. package/src/commands/resume.js +389 -0
  35. package/src/commands/status.js +196 -3
  36. package/src/commands/step.js +947 -0
  37. package/src/commands/stop.js +65 -33
  38. package/src/commands/template-list.js +33 -0
  39. package/src/commands/template-set.js +279 -0
  40. package/src/commands/update.js +24 -3
  41. package/src/commands/validate.js +20 -11
  42. package/src/commands/verify.js +71 -0
  43. package/src/commands/watch.js +112 -25
  44. package/src/lib/adapters/api-proxy-adapter.js +1076 -0
  45. package/src/lib/adapters/local-cli-adapter.js +337 -0
  46. package/src/lib/adapters/manual-adapter.js +169 -0
  47. package/src/lib/blocked-state.js +94 -0
  48. package/src/lib/config.js +143 -12
  49. package/src/lib/context-compressor.js +121 -0
  50. package/src/lib/context-section-parser.js +220 -0
  51. package/src/lib/coordinator-acceptance.js +428 -0
  52. package/src/lib/coordinator-config.js +461 -0
  53. package/src/lib/coordinator-dispatch.js +276 -0
  54. package/src/lib/coordinator-gates.js +487 -0
  55. package/src/lib/coordinator-hooks.js +239 -0
  56. package/src/lib/coordinator-recovery.js +523 -0
  57. package/src/lib/coordinator-state.js +365 -0
  58. package/src/lib/cross-repo-context.js +247 -0
  59. package/src/lib/dashboard/bridge-server.js +284 -0
  60. package/src/lib/dashboard/file-watcher.js +93 -0
  61. package/src/lib/dashboard/state-reader.js +96 -0
  62. package/src/lib/dispatch-bundle.js +568 -0
  63. package/src/lib/dispatch-manifest.js +252 -0
  64. package/src/lib/filter-agents.js +12 -0
  65. package/src/lib/gate-evaluator.js +285 -0
  66. package/src/lib/generate-vscode.js +158 -68
  67. package/src/lib/governed-state.js +2139 -0
  68. package/src/lib/governed-templates.js +145 -0
  69. package/src/lib/hook-runner.js +788 -0
  70. package/src/lib/next-owner.js +61 -6
  71. package/src/lib/normalized-config.js +539 -0
  72. package/src/lib/notify.js +14 -12
  73. package/src/lib/plugin-config-schema.js +192 -0
  74. package/src/lib/plugins.js +692 -0
  75. package/src/lib/prompt-core.js +108 -0
  76. package/src/lib/protocol-conformance.js +291 -0
  77. package/src/lib/reference-conformance-adapter.js +717 -0
  78. package/src/lib/repo-observer.js +597 -0
  79. package/src/lib/repo.js +0 -31
  80. package/src/lib/safe-write.js +44 -0
  81. package/src/lib/schema.js +189 -0
  82. package/src/lib/schemas/turn-result.schema.json +205 -0
  83. package/src/lib/seed-prompt-polling.js +15 -73
  84. package/src/lib/seed-prompt.js +17 -63
  85. package/src/lib/token-budget.js +206 -0
  86. package/src/lib/token-counter.js +27 -0
  87. package/src/lib/turn-paths.js +67 -0
  88. package/src/lib/turn-result-validator.js +496 -0
  89. package/src/lib/validation.js +167 -19
  90. package/src/lib/verify-command.js +72 -0
  91. package/src/templates/governed/api-service.json +31 -0
  92. package/src/templates/governed/cli-tool.json +30 -0
  93. package/src/templates/governed/generic.json +10 -0
  94. package/src/templates/governed/web-app.json +30 -0
@@ -0,0 +1,145 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+
7
+ export const GOVERNED_TEMPLATES_DIR = join(__dirname, '../templates/governed');
8
+ export const VALID_GOVERNED_TEMPLATE_IDS = Object.freeze([
9
+ 'generic',
10
+ 'api-service',
11
+ 'cli-tool',
12
+ 'web-app',
13
+ ]);
14
+
15
+ const VALID_PROMPT_OVERRIDE_ROLES = new Set(['pm', 'dev', 'qa', 'eng_director']);
16
+
17
+ function validatePlanningArtifacts(artifacts, errors) {
18
+ if (!Array.isArray(artifacts)) {
19
+ errors.push('planning_artifacts must be an array');
20
+ return;
21
+ }
22
+
23
+ const seenFilenames = new Set();
24
+ for (const artifact of artifacts) {
25
+ if (!artifact || typeof artifact !== 'object' || Array.isArray(artifact)) {
26
+ errors.push('planning_artifacts entries must be objects');
27
+ continue;
28
+ }
29
+
30
+ if (typeof artifact.filename !== 'string' || !artifact.filename.trim()) {
31
+ errors.push('planning_artifacts.filename must be a non-empty string');
32
+ } else if (seenFilenames.has(artifact.filename)) {
33
+ errors.push(`planning_artifacts contains duplicate filename "${artifact.filename}"`);
34
+ } else {
35
+ seenFilenames.add(artifact.filename);
36
+ }
37
+
38
+ if (typeof artifact.content_template !== 'string' || !artifact.content_template.trim()) {
39
+ errors.push(`planning_artifacts["${artifact.filename || '?'}"].content_template must be a non-empty string`);
40
+ }
41
+ }
42
+ }
43
+
44
+ function validatePromptOverrides(promptOverrides, errors) {
45
+ if (promptOverrides === undefined) return;
46
+ if (!promptOverrides || typeof promptOverrides !== 'object' || Array.isArray(promptOverrides)) {
47
+ errors.push('prompt_overrides must be an object when provided');
48
+ return;
49
+ }
50
+
51
+ for (const [roleId, content] of Object.entries(promptOverrides)) {
52
+ if (!VALID_PROMPT_OVERRIDE_ROLES.has(roleId)) {
53
+ errors.push(`prompt_overrides contains unknown role "${roleId}"`);
54
+ }
55
+ if (typeof content !== 'string' || !content.trim()) {
56
+ errors.push(`prompt_overrides["${roleId}"] must be a non-empty string`);
57
+ }
58
+ }
59
+ }
60
+
61
+ function validateAcceptanceHints(acceptanceHints, errors) {
62
+ if (acceptanceHints === undefined) return;
63
+ if (!Array.isArray(acceptanceHints)) {
64
+ errors.push('acceptance_hints must be an array when provided');
65
+ return;
66
+ }
67
+
68
+ for (const hint of acceptanceHints) {
69
+ if (typeof hint !== 'string' || !hint.trim()) {
70
+ errors.push('acceptance_hints entries must be non-empty strings');
71
+ }
72
+ }
73
+ }
74
+
75
+ export function validateGovernedTemplateManifest(manifest, expectedId = null) {
76
+ const errors = [];
77
+
78
+ if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
79
+ return { ok: false, errors: ['manifest must be a JSON object'] };
80
+ }
81
+
82
+ if (typeof manifest.id !== 'string' || !manifest.id.trim()) {
83
+ errors.push('id must be a non-empty string');
84
+ } else if (expectedId && manifest.id !== expectedId) {
85
+ errors.push(`id must match expected template id "${expectedId}"`);
86
+ }
87
+
88
+ if (typeof manifest.display_name !== 'string' || !manifest.display_name.trim()) {
89
+ errors.push('display_name must be a non-empty string');
90
+ }
91
+
92
+ if (typeof manifest.description !== 'string' || !manifest.description.trim()) {
93
+ errors.push('description must be a non-empty string');
94
+ }
95
+
96
+ if (typeof manifest.version !== 'string' || !manifest.version.trim()) {
97
+ errors.push('version must be a non-empty string');
98
+ }
99
+
100
+ if (!Array.isArray(manifest.protocol_compatibility) || manifest.protocol_compatibility.length === 0) {
101
+ errors.push('protocol_compatibility must be a non-empty array');
102
+ } else {
103
+ for (const version of manifest.protocol_compatibility) {
104
+ if (typeof version !== 'string' || !version.trim()) {
105
+ errors.push('protocol_compatibility entries must be non-empty strings');
106
+ }
107
+ }
108
+ }
109
+
110
+ validatePlanningArtifacts(manifest.planning_artifacts, errors);
111
+ validatePromptOverrides(manifest.prompt_overrides, errors);
112
+ validateAcceptanceHints(manifest.acceptance_hints, errors);
113
+
114
+ return { ok: errors.length === 0, errors };
115
+ }
116
+
117
+ export function loadGovernedTemplate(templateId) {
118
+ if (!VALID_GOVERNED_TEMPLATE_IDS.includes(templateId)) {
119
+ const validIds = VALID_GOVERNED_TEMPLATE_IDS.join(', ');
120
+ throw new Error(`Unknown template "${templateId}". Valid templates: ${validIds}`);
121
+ }
122
+
123
+ const manifestPath = join(GOVERNED_TEMPLATES_DIR, `${templateId}.json`);
124
+ if (!existsSync(manifestPath)) {
125
+ throw new Error(`Template "${templateId}" is registered but its manifest is missing.`);
126
+ }
127
+
128
+ let manifest;
129
+ try {
130
+ manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
131
+ } catch (err) {
132
+ throw new Error(`Template "${templateId}" manifest is invalid JSON: ${err.message}`);
133
+ }
134
+
135
+ const validation = validateGovernedTemplateManifest(manifest, templateId);
136
+ if (!validation.ok) {
137
+ throw new Error(`Template "${templateId}" manifest is invalid: ${validation.errors.join('; ')}`);
138
+ }
139
+
140
+ return manifest;
141
+ }
142
+
143
+ export function loadAllGovernedTemplates() {
144
+ return VALID_GOVERNED_TEMPLATE_IDS.map((templateId) => loadGovernedTemplate(templateId));
145
+ }