@adityaaria/agent-os 1.0.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 (129) hide show
  1. package/AGENTS.md +41 -0
  2. package/AGENT_OS_BOOTSTRAP.md +29 -0
  3. package/ENTRYPOINT.md +118 -0
  4. package/LICENSE +21 -0
  5. package/README.md +230 -0
  6. package/adapters/antigravity/README.md +9 -0
  7. package/adapters/antigravity/plugin.json +13 -0
  8. package/adapters/claude/CLAUDE.md +16 -0
  9. package/adapters/claude/README.md +10 -0
  10. package/adapters/codex/README.md +20 -0
  11. package/adapters/cursor/README.md +9 -0
  12. package/adapters/cursor/agent-os.rules.md +18 -0
  13. package/bin/agent-os.mjs +98 -0
  14. package/core/AUTO_PROJECT_DETECTOR.md +99 -0
  15. package/core/COMPLIANCE_GATE.md +19 -0
  16. package/core/FRAMEWORK_AUDITOR.md +35 -0
  17. package/core/KNOWLEDGE_REGENERATOR.md +30 -0
  18. package/core/KNOWLEDGE_VALIDATOR.md +29 -0
  19. package/core/PROJECT_CONTEXT_STANDARD.md +19 -0
  20. package/core/QUALITY_GATES.md +42 -0
  21. package/core/REPORTING_STANDARD.md +47 -0
  22. package/core/SKILL_ORCHESTRATOR.md +63 -0
  23. package/core/TASK_ROUTER.md +33 -0
  24. package/core/TRACEABILITY_STANDARD.md +40 -0
  25. package/package.json +28 -0
  26. package/scripts/install.mjs +690 -0
  27. package/scripts/lib/cli-utils.mjs +148 -0
  28. package/scripts/lib/run-utils.mjs +185 -0
  29. package/scripts/lib/telegram-audit-log.mjs +50 -0
  30. package/scripts/lib/telegram-bot-utils.mjs +413 -0
  31. package/scripts/lib/telegram-utils.mjs +127 -0
  32. package/scripts/orchestrate.mjs +230 -0
  33. package/scripts/quality-static.mjs +19 -0
  34. package/scripts/report-export.mjs +86 -0
  35. package/scripts/report-notify.mjs +169 -0
  36. package/scripts/run-execution.mjs +83 -0
  37. package/scripts/run-list.mjs +44 -0
  38. package/scripts/run-status.mjs +38 -0
  39. package/scripts/run-step.mjs +173 -0
  40. package/scripts/setup-wizard.mjs +116 -0
  41. package/scripts/sync-runtime.mjs +87 -0
  42. package/scripts/telegram-bot.mjs +88 -0
  43. package/scripts/telegram-check.mjs +94 -0
  44. package/scripts/telegram-poll.mjs +176 -0
  45. package/scripts/validate-framework.mjs +290 -0
  46. package/skills/api-contract-audit/SKILL.md +26 -0
  47. package/skills/api-contract-audit/checklist.md +16 -0
  48. package/skills/api-contract-audit/examples.md +3 -0
  49. package/skills/api-contract-audit/report-template.md +39 -0
  50. package/skills/api-contract-audit/workflow.md +15 -0
  51. package/skills/audit/SKILL.md +28 -0
  52. package/skills/audit/checklist.md +18 -0
  53. package/skills/audit/examples.md +26 -0
  54. package/skills/audit/report-template.md +39 -0
  55. package/skills/audit/workflow.md +15 -0
  56. package/skills/bug-fix/SKILL.md +25 -0
  57. package/skills/bug-fix/checklist.md +18 -0
  58. package/skills/bug-fix/examples.md +26 -0
  59. package/skills/bug-fix/report-template.md +39 -0
  60. package/skills/bug-fix/workflow.md +10 -0
  61. package/skills/database-impact-analysis/SKILL.md +27 -0
  62. package/skills/database-impact-analysis/checklist.md +16 -0
  63. package/skills/database-impact-analysis/examples.md +3 -0
  64. package/skills/database-impact-analysis/report-template.md +39 -0
  65. package/skills/database-impact-analysis/workflow.md +14 -0
  66. package/skills/enhancement/SKILL.md +27 -0
  67. package/skills/enhancement/checklist.md +19 -0
  68. package/skills/enhancement/examples.md +26 -0
  69. package/skills/enhancement/report-template.md +39 -0
  70. package/skills/enhancement/workflow.md +10 -0
  71. package/skills/enterprise-certification/SKILL.md +19 -0
  72. package/skills/enterprise-certification/checklist.md +17 -0
  73. package/skills/enterprise-certification/report-template.md +39 -0
  74. package/skills/enterprise-certification/workflow.md +14 -0
  75. package/skills/knowledge-evolution/SKILL.md +23 -0
  76. package/skills/knowledge-evolution/checklist.md +17 -0
  77. package/skills/knowledge-evolution/report-template.md +39 -0
  78. package/skills/knowledge-evolution/workflow.md +14 -0
  79. package/skills/new-page/SKILL.md +26 -0
  80. package/skills/new-page/checklist.md +21 -0
  81. package/skills/new-page/examples.md +26 -0
  82. package/skills/new-page/report-template.md +39 -0
  83. package/skills/new-page/workflow.md +10 -0
  84. package/skills/project-onboarding/SKILL.md +27 -0
  85. package/skills/project-onboarding/checklist.md +18 -0
  86. package/skills/project-onboarding/examples.md +26 -0
  87. package/skills/project-onboarding/report-template.md +39 -0
  88. package/skills/project-onboarding/workflow.md +9 -0
  89. package/skills/release-readiness/SKILL.md +27 -0
  90. package/skills/release-readiness/checklist.md +16 -0
  91. package/skills/release-readiness/examples.md +3 -0
  92. package/skills/release-readiness/report-template.md +39 -0
  93. package/skills/release-readiness/workflow.md +14 -0
  94. package/skills/repository-health/SKILL.md +26 -0
  95. package/skills/repository-health/checklist.md +20 -0
  96. package/skills/repository-health/report-template.md +39 -0
  97. package/skills/repository-health/workflow.md +14 -0
  98. package/skills/selenium-e2e/SKILL.md +83 -0
  99. package/skills/selenium-e2e/checklist.md +29 -0
  100. package/skills/selenium-e2e/examples.md +26 -0
  101. package/skills/selenium-e2e/report-template.md +39 -0
  102. package/skills/selenium-e2e/workflow.md +9 -0
  103. package/skills/self-audit/SKILL.md +19 -0
  104. package/skills/self-audit/checklist.md +14 -0
  105. package/skills/self-audit/report-template.md +39 -0
  106. package/skills/self-audit/workflow.md +11 -0
  107. package/skills/traceability-analysis/SKILL.md +25 -0
  108. package/skills/traceability-analysis/checklist.md +17 -0
  109. package/skills/traceability-analysis/examples.md +3 -0
  110. package/skills/traceability-analysis/report-template.md +39 -0
  111. package/skills/traceability-analysis/workflow.md +17 -0
  112. package/templates/API_RULES.md +20 -0
  113. package/templates/ARCHITECTURE.md +20 -0
  114. package/templates/BUSINESS_FLOW.md +20 -0
  115. package/templates/COMMANDS.md +20 -0
  116. package/templates/DATABASE_RULES.md +20 -0
  117. package/templates/DEPENDENCY_MAP.md +20 -0
  118. package/templates/DEPLOYMENT_RULES.md +20 -0
  119. package/templates/DOMAIN_MODEL.md +20 -0
  120. package/templates/FE_BE_TRACEABILITY.md +20 -0
  121. package/templates/KNOWN_LIMITATIONS.md +20 -0
  122. package/templates/MODULE_CATALOG.md +20 -0
  123. package/templates/PROJECT_PROFILE.md +20 -0
  124. package/templates/RISK_REGISTER.md +20 -0
  125. package/templates/SECURITY_RULES.md +20 -0
  126. package/templates/TECHNICAL_DEBT.md +20 -0
  127. package/templates/TECH_STACK.md +20 -0
  128. package/templates/TESTING_RULES.md +47 -0
  129. package/templates/UI_UX_RULES.md +20 -0
@@ -0,0 +1,148 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Creates a CLI argument parser from process.argv.
6
+ * @param {string[]} argv - process.argv.slice(2)
7
+ */
8
+ export function createCli(argv) {
9
+ const args = [...argv];
10
+
11
+ function hasFlag(name) {
12
+ return args.includes(name);
13
+ }
14
+
15
+ function takeOption(name) {
16
+ const index = args.indexOf(name);
17
+ if (index === -1) return null;
18
+ const value = args[index + 1] ?? null;
19
+ args.splice(index, 2);
20
+ return value;
21
+ }
22
+
23
+ return { hasFlag, takeOption, args };
24
+ }
25
+
26
+ /**
27
+ * Returns true if the user passed --help or -h.
28
+ * @param {string[]} argv
29
+ */
30
+ export function wantsHelp(argv) {
31
+ return argv.includes('--help') || argv.includes('-h');
32
+ }
33
+
34
+ /**
35
+ * Renders a formatted help text block and exits cleanly.
36
+ * @param {object} config
37
+ * @param {string} config.command - The subcommand name
38
+ * @param {string} config.description - One-line description
39
+ * @param {string[]} config.usage - Usage lines (one per variant)
40
+ * @param {Array<{flag: string, desc: string, default?: string}>} [config.required] - Required flags
41
+ * @param {Array<{flag: string, desc: string, default?: string}>} [config.options] - Optional flags
42
+ * @param {string[]} [config.examples] - Example command lines
43
+ */
44
+ export function showHelp(config) {
45
+ const lines = [];
46
+ lines.push(`agent-os ${config.command} — ${config.description}`);
47
+ lines.push('');
48
+
49
+ lines.push('Usage:');
50
+ for (const usage of config.usage) {
51
+ lines.push(` ${usage}`);
52
+ }
53
+ lines.push('');
54
+
55
+ if (config.required?.length) {
56
+ lines.push('Required:');
57
+ const maxLen = Math.max(...config.required.map((o) => o.flag.length));
58
+ for (const opt of config.required) {
59
+ lines.push(` ${opt.flag.padEnd(maxLen + 2)} ${opt.desc}`);
60
+ }
61
+ lines.push('');
62
+ }
63
+
64
+ if (config.options?.length) {
65
+ lines.push('Options:');
66
+ const maxLen = Math.max(...config.options.map((o) => o.flag.length));
67
+ for (const opt of config.options) {
68
+ const defaultStr = opt.default ? ` [default: ${opt.default}]` : '';
69
+ lines.push(` ${opt.flag.padEnd(maxLen + 2)} ${opt.desc}${defaultStr}`);
70
+ }
71
+ lines.push('');
72
+ }
73
+
74
+ if (config.examples?.length) {
75
+ lines.push('Examples:');
76
+ for (const example of config.examples) {
77
+ lines.push(` ${example}`);
78
+ }
79
+ lines.push('');
80
+ }
81
+
82
+ console.log(lines.join('\n'));
83
+ process.exit(0);
84
+ }
85
+
86
+ /**
87
+ * Collects multiple validation errors, then displays them all at once with
88
+ * a usage example, and exits with code 1.
89
+ * @param {string[]} errors - List of error messages
90
+ * @param {string} [example] - Example command to show
91
+ * @param {string} [command] - Command name for --help hint
92
+ */
93
+ export function failAll(errors, example, command) {
94
+ if (errors.length === 0) return;
95
+
96
+ console.error(`\n✗ ERROR: ${errors.length} issue${errors.length > 1 ? 's' : ''} found:\n`);
97
+ for (const error of errors) {
98
+ console.error(` • ${error}`);
99
+ }
100
+
101
+ if (example) {
102
+ console.error(`\nExample:`);
103
+ console.error(` ${example}`);
104
+ }
105
+
106
+ if (command) {
107
+ console.error(`\nRun 'agent-os ${command} --help' for full usage.`);
108
+ }
109
+
110
+ console.error('');
111
+ process.exit(1);
112
+ }
113
+
114
+ /**
115
+ * Simple single-error fail (for runtime errors after validation).
116
+ * @param {string} message
117
+ */
118
+ export function fail(message) {
119
+ console.error(message);
120
+ process.exit(1);
121
+ }
122
+
123
+ /**
124
+ * Resolves a CLI flag value with a smart default.
125
+ * If the value is already set (from CLI), returns it.
126
+ * Otherwise checks if the default file/directory exists and returns it.
127
+ * @param {string|null} value - The CLI-provided value
128
+ * @param {string} defaultPath - The default path to try
129
+ * @returns {string|null}
130
+ */
131
+ export function resolveDefault(value, defaultPath) {
132
+ if (value) return value;
133
+ const resolved = path.resolve(process.cwd(), defaultPath);
134
+ if (fs.existsSync(resolved)) return resolved;
135
+ return null;
136
+ }
137
+
138
+ /**
139
+ * Resolves a default that does not require the file to exist yet
140
+ * (e.g., state files that will be created on first run).
141
+ * @param {string|null} value
142
+ * @param {string} defaultPath
143
+ * @returns {string|null}
144
+ */
145
+ export function resolveDefaultPath(value, defaultPath) {
146
+ if (value) return value;
147
+ return defaultPath;
148
+ }
@@ -0,0 +1,185 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export const runStatuses = ['pending', 'running', 'passed', 'failed', 'blocked'];
5
+
6
+ export function buildStatusCounts(steps) {
7
+ const counts = Object.fromEntries(runStatuses.map((status) => [status, 0]));
8
+ for (const step of steps) {
9
+ if (counts[step.status] === undefined) counts[step.status] = 0;
10
+ counts[step.status]++;
11
+ }
12
+ return counts;
13
+ }
14
+
15
+ export function deriveRunStatus(steps) {
16
+ const counts = buildStatusCounts(steps);
17
+ if (counts.failed > 0 || counts.blocked > 0) return 'failed';
18
+ if (counts.running > 0) return 'running';
19
+ if (steps.length > 0 && counts.passed === steps.length) return 'complete';
20
+ return 'pending';
21
+ }
22
+
23
+ function extractSection(content, sectionName) {
24
+ const regex = new RegExp(`^# ${sectionName}\\n([\\s\\S]*?)(?:\\n# |$)`, 'm');
25
+ const match = content.match(regex);
26
+ return match ? match[1].trim() : null;
27
+ }
28
+
29
+ export function summarizeRun(runDir) {
30
+ const planPath = path.join(runDir, 'plan.json');
31
+ const stepsPath = path.join(runDir, 'steps.json');
32
+ if (!fs.existsSync(planPath) || !fs.existsSync(stepsPath)) return null;
33
+
34
+ const plan = JSON.parse(fs.readFileSync(planPath, 'utf8'));
35
+ const steps = JSON.parse(fs.readFileSync(stepsPath, 'utf8'));
36
+
37
+ const reportPath = path.join(runDir, 'master-report.md');
38
+ let reportDetails = null;
39
+ if (fs.existsSync(reportPath)) {
40
+ const content = fs.readFileSync(reportPath, 'utf8');
41
+ reportDetails = {
42
+ evidence: extractSection(content, 'Evidence')
43
+ };
44
+ }
45
+
46
+ return {
47
+ runDir,
48
+ runId: plan.run?.id ?? path.basename(runDir),
49
+ status: deriveRunStatus(steps),
50
+ total: steps.length,
51
+ counts: buildStatusCounts(steps),
52
+ plan,
53
+ steps,
54
+ reportDetails
55
+ };
56
+ }
57
+
58
+ export function collectRuns(runRoot) {
59
+ const absoluteRunRoot = path.resolve(process.cwd(), runRoot);
60
+ if (!fs.existsSync(absoluteRunRoot)) {
61
+ throw new Error(`Run root not found: ${absoluteRunRoot}`);
62
+ }
63
+
64
+ return fs.readdirSync(absoluteRunRoot, { withFileTypes: true })
65
+ .filter((entry) => entry.isDirectory())
66
+ .map((entry) => summarizeRun(path.join(absoluteRunRoot, entry.name)))
67
+ .filter(Boolean)
68
+ .sort((a, b) => a.runId.localeCompare(b.runId));
69
+ }
70
+
71
+ export function collectRun(runDir) {
72
+ const absoluteRunDir = path.resolve(process.cwd(), runDir);
73
+ const summary = summarizeRun(absoluteRunDir);
74
+ if (!summary) {
75
+ throw new Error(`Run directory is missing plan.json or steps.json: ${absoluteRunDir}`);
76
+ }
77
+ return summary;
78
+ }
79
+
80
+ export function loadReportChannel(channelConfig, channelName) {
81
+ const absoluteConfigPath = path.resolve(process.cwd(), channelConfig);
82
+ if (!fs.existsSync(absoluteConfigPath)) {
83
+ throw new Error(`Channel config not found: ${absoluteConfigPath}`);
84
+ }
85
+
86
+ const config = JSON.parse(fs.readFileSync(absoluteConfigPath, 'utf8'));
87
+ const channel = config.channels?.[channelName];
88
+ if (!channel) {
89
+ throw new Error(`Report channel not found: ${channelName}`);
90
+ }
91
+
92
+ return {
93
+ name: channelName,
94
+ configPath: absoluteConfigPath,
95
+ outputBaseDir: path.dirname(absoluteConfigPath),
96
+ channel
97
+ };
98
+ }
99
+
100
+ export function assertEnabledChannel(channelContext) {
101
+ if (channelContext.channel.enabled === false) {
102
+ throw new Error(`Report channel is disabled: ${channelContext.name}`);
103
+ }
104
+ }
105
+
106
+ function escapeCsvValue(value) {
107
+ const text = String(value ?? '');
108
+ if (!/[",\n\r]/.test(text)) return text;
109
+ return `"${text.replaceAll('"', '""')}"`;
110
+ }
111
+
112
+ export function renderRunSummariesCsv(summaries) {
113
+ const rows = Array.isArray(summaries) ? summaries : [summaries];
114
+ const headers = ['runId', 'status', 'total', 'pending', 'running', 'passed', 'failed', 'blocked', 'runDir'];
115
+ const lines = [headers.join(',')];
116
+
117
+ for (const summary of rows) {
118
+ lines.push([
119
+ summary.runId,
120
+ summary.status,
121
+ summary.total,
122
+ summary.counts.pending ?? 0,
123
+ summary.counts.running ?? 0,
124
+ summary.counts.passed ?? 0,
125
+ summary.counts.failed ?? 0,
126
+ summary.counts.blocked ?? 0,
127
+ summary.runDir
128
+ ].map(escapeCsvValue).join(','));
129
+ }
130
+
131
+ return `${lines.join('\n')}\n`;
132
+ }
133
+
134
+ export function renderReport(plan) {
135
+ const sectionBody = {
136
+ 'Executive Summary': [
137
+ `Trigger: ${plan.trigger}`,
138
+ `Prompt: ${plan.prompt}`,
139
+ `Validation Status: ${plan.validation.status}`
140
+ ],
141
+ Scope: [
142
+ `Mode: ${plan.mode}`,
143
+ `Skill Chain: ${plan.skillChain.join(' -> ')}`
144
+ ],
145
+ 'Knowledge Confidence': [
146
+ 'Score: N/A. Reason: Execution stub does not inspect project knowledge.'
147
+ ],
148
+ 'Knowledge Classification': [
149
+ 'Classification: N/A. Reason: Execution stub only renders a validated plan.'
150
+ ],
151
+ 'Traceability Matrix': [
152
+ '| Step | Skill | Depends On | Status |',
153
+ '| ---- | ----- | ---------- | ------ |',
154
+ ...plan.executionPlan.map((step) => (
155
+ `| ${step.step} | ${step.skill} | ${step.dependsOn.join(', ') || 'N/A. Reason: First step.'} | ${step.status} |`
156
+ ))
157
+ ],
158
+ Evidence: plan.executionEvidence?.length > 0
159
+ ? plan.executionEvidence
160
+ : ['N/A. Reason: Skills were not executed by this stub.'],
161
+ 'Root Cause': [
162
+ 'N/A. Reason: Root cause is produced by the executing skill.'
163
+ ],
164
+ Impact: [
165
+ 'N/A. Reason: Impact is produced by the executing skill.'
166
+ ],
167
+ Recommendation: [
168
+ 'Quick Win: Review this validated execution plan before running skills.',
169
+ 'Long Term Improvement: Replace this stub with gated skill execution.'
170
+ ],
171
+ 'Quality Gate': [
172
+ `Plan Validation: ${plan.validation.status}`
173
+ ],
174
+ 'Enterprise Readiness': [
175
+ 'N/A. Reason: Enterprise readiness is assessed after execution evidence exists.'
176
+ ],
177
+ 'Final Decision': [
178
+ plan.validation.status === 'PASS' ? 'CONDITIONAL PASS' : 'FAIL'
179
+ ]
180
+ };
181
+
182
+ return plan.masterReport.sections
183
+ .map((section) => `# ${section}\n${sectionBody[section].join('\n')}`)
184
+ .join('\n\n') + '\n';
185
+ }
@@ -0,0 +1,50 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Appends an audit entry to the telegram audit log JSONL file.
6
+ *
7
+ * @param {Object} options
8
+ * @param {string} options.runRoot - The absolute path to the .agent-os/runs or equivalent root directory
9
+ * @param {Object} options.entry - The audit log entry to append
10
+ */
11
+ export function appendAuditEntry({ runRoot, entry }) {
12
+ if (!runRoot) return;
13
+
14
+ const logPath = path.join(runRoot, '..', 'project', 'reports', 'telegram-audit-log.jsonl');
15
+
16
+ // Ensure directory exists
17
+ fs.mkdirSync(path.dirname(logPath), { recursive: true });
18
+
19
+ // Prepare entry with timestamp if not provided
20
+ const logEntry = {
21
+ timestamp: new Date().toISOString(),
22
+ ...entry
23
+ };
24
+
25
+ // Append as JSONL
26
+ fs.appendFileSync(logPath, `${JSON.stringify(logEntry)}\n`, 'utf8');
27
+ }
28
+
29
+ /**
30
+ * Reads and parses the telegram audit log.
31
+ *
32
+ * @param {Object} options
33
+ * @param {string} options.runRoot - The absolute path to the .agent-os/runs or equivalent root directory
34
+ * @returns {Array<Object>} The parsed audit log entries
35
+ */
36
+ export function readAuditLog({ runRoot }) {
37
+ if (!runRoot) return [];
38
+
39
+ const logPath = path.join(runRoot, '..', 'project', 'reports', 'telegram-audit-log.jsonl');
40
+ if (!fs.existsSync(logPath)) {
41
+ return [];
42
+ }
43
+
44
+ const content = fs.readFileSync(logPath, 'utf8');
45
+ return content
46
+ .split('\n')
47
+ .map(line => line.trim())
48
+ .filter(Boolean)
49
+ .map(line => JSON.parse(line));
50
+ }