@mamdouh-aboammar/agentic-workflow 1.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.
- package/.claude-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +13 -0
- package/.skills.json +19 -0
- package/AGENTS.md +1344 -0
- package/CLAUDE.md +178 -0
- package/GEMINI.md +102 -0
- package/LICENSE +21 -0
- package/README.md +350 -0
- package/SKILL.md +132 -0
- package/bin/agentic-hooks.sh +79 -0
- package/bin/cli.js +1060 -0
- package/core/__init__.py +52 -0
- package/core/ai_evaluator.py +117 -0
- package/core/autopilot_engine.py +368 -0
- package/core/clean_code_guard.py +188 -0
- package/core/engine_py/__init__.py +29 -0
- package/core/engine_py/agent_worker.py +136 -0
- package/core/engine_py/decider.py +150 -0
- package/core/engine_py/energy.py +45 -0
- package/core/engine_py/event_bus.py +63 -0
- package/core/engine_py/executor.py +186 -0
- package/core/engine_py/models.py +193 -0
- package/core/engine_py/queue.py +314 -0
- package/core/engine_py/runner.py +116 -0
- package/core/engine_py/system_workers.py +70 -0
- package/core/engine_py/toon_adapter.py +586 -0
- package/core/engine_py/verification_controller.py +208 -0
- package/core/engine_py/worker.py +167 -0
- package/core/engine_spec/event_schema.json +65 -0
- package/core/engine_spec/example_workflow.yaml +73 -0
- package/core/engine_spec/workflow_schema.json +127 -0
- package/core/hooks/__init__.py +29 -0
- package/core/hooks/adapters/__init__.py +25 -0
- package/core/hooks/adapters/claude_adapter.py +83 -0
- package/core/hooks/adapters/cli_agent_adapter.py +82 -0
- package/core/hooks/adapters/codex_adapter.py +78 -0
- package/core/hooks/adapters/cursor_adapter.py +73 -0
- package/core/hooks/adapters/gemini_adapter.py +93 -0
- package/core/hooks/adapters/homebrew_adapter.py +69 -0
- package/core/hooks/adapters/mcp_proxy.py +133 -0
- package/core/hooks/adapters/shell_adapter.py +65 -0
- package/core/hooks/dispatcher.py +118 -0
- package/core/hooks/policy_engine.py +375 -0
- package/core/hooks/session_end.py +141 -0
- package/core/hooks/types.py +147 -0
- package/core/integrations/__init__.py +28 -0
- package/core/integrations/installer.py +225 -0
- package/core/integrations/lifecycle_director.py +175 -0
- package/core/integrations/registry.py +105 -0
- package/core/multi_agent_system.py +164 -0
- package/core/skills_indexer.py +742 -0
- package/core/system/__init__.py +25 -0
- package/core/system/announcements.py +72 -0
- package/core/system/dependencies.py +69 -0
- package/core/system/doctor.py +171 -0
- package/core/system/health.py +144 -0
- package/core/system/installer.py +137 -0
- package/core/system/notifications.py +97 -0
- package/core/system/refresher.py +110 -0
- package/core/system/updater.py +167 -0
- package/core/system/version_tracker.py +65 -0
- package/docs/architecture_plan.md +7 -0
- package/docs/guides/failure-recovery.md +714 -0
- package/docs/implementation_summary.md +10 -0
- package/docs/protocols/autopilot-execution.md +148 -0
- package/docs/protocols/code-change-protocol.md +49 -0
- package/docs/protocols/context-preservation-detail.md +114 -0
- package/docs/protocols/quality-gates.md +110 -0
- package/docs/protocols/ulw-mode.md +60 -0
- package/docs/research_findings.md +10 -0
- package/docs/solutions/autonomous-autopilot-engine-architecture.md +38 -0
- package/install.sh +111 -0
- package/marketplace.json +37 -0
- package/package.json +81 -0
- package/skills/agentic-workflow/SKILL.md +132 -0
- package/skills/agentic-workflow/skill-spec.json +100 -0
- package/soul.md +445 -0
- package/src/engine_ts/decider.ts +186 -0
- package/src/engine_ts/event-bus.ts +57 -0
- package/src/engine_ts/executor.ts +262 -0
- package/src/engine_ts/index.ts +12 -0
- package/src/engine_ts/queue.ts +93 -0
- package/src/engine_ts/runner.ts +108 -0
- package/src/engine_ts/skills-indexer.ts +264 -0
- package/src/engine_ts/toon-adapter.ts +91 -0
- package/src/engine_ts/types.ts +134 -0
- package/src/engine_ts/verification-controller.ts +204 -0
- package/src/engine_ts/worker.ts +280 -0
- package/src/hooks/adapters/claude-adapter.ts +54 -0
- package/src/hooks/adapters/cli-agent-adapter.ts +46 -0
- package/src/hooks/adapters/codex-adapter.ts +69 -0
- package/src/hooks/adapters/cursor-adapter.ts +60 -0
- package/src/hooks/adapters/gemini-adapter.ts +71 -0
- package/src/hooks/adapters/homebrew-adapter.ts +36 -0
- package/src/hooks/adapters/mcp-proxy.ts +66 -0
- package/src/hooks/adapters/shell-adapter.ts +42 -0
- package/src/hooks/dispatcher.ts +113 -0
- package/src/hooks/index.ts +16 -0
- package/src/hooks/policy-engine.ts +376 -0
- package/src/hooks/session-end.ts +125 -0
- package/src/hooks/types.ts +61 -0
- package/src/index.d.ts +34 -0
- package/src/index.ts +23 -0
- package/src/integrations/index.ts +7 -0
- package/src/integrations/installer.ts +208 -0
- package/src/integrations/lifecycle-director.ts +139 -0
- package/src/integrations/registry.ts +82 -0
- package/src/system/announcements.ts +143 -0
- package/src/system/dependencies.ts +176 -0
- package/src/system/doctor.ts +374 -0
- package/src/system/health.ts +270 -0
- package/src/system/index.ts +14 -0
- package/src/system/installer.ts +262 -0
- package/src/system/notifications.ts +180 -0
- package/src/system/refresher.ts +207 -0
- package/src/system/types.ts +268 -0
- package/src/system/updater.ts +219 -0
- package/src/system/version-tracker.ts +137 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Agentic Hooks Framework (UAHF) — TypeScript Types & Data Models
|
|
3
|
+
* =========================================================================
|
|
4
|
+
* Canonical types for multi-platform hook events, verdicts, and policies in Bun/TypeScript.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type HookSource =
|
|
8
|
+
| 'claude'
|
|
9
|
+
| 'cursor'
|
|
10
|
+
| 'antigravity'
|
|
11
|
+
| 'codex'
|
|
12
|
+
| 'kimi'
|
|
13
|
+
| 'bash'
|
|
14
|
+
| 'terminal'
|
|
15
|
+
| 'homebrew'
|
|
16
|
+
| 'mcp'
|
|
17
|
+
| 'cli';
|
|
18
|
+
|
|
19
|
+
export type HookType =
|
|
20
|
+
| 'pre_tool'
|
|
21
|
+
| 'post_tool'
|
|
22
|
+
| 'pre_command'
|
|
23
|
+
| 'post_command'
|
|
24
|
+
| 'session_start'
|
|
25
|
+
| 'session_end'
|
|
26
|
+
| 'error_trap';
|
|
27
|
+
|
|
28
|
+
export type HookVerdict = 'allow' | 'block' | 'mutate' | 'warn' | 'ask_user';
|
|
29
|
+
|
|
30
|
+
export interface HookEvent {
|
|
31
|
+
event_id: string;
|
|
32
|
+
source: HookSource;
|
|
33
|
+
hook_type: HookType;
|
|
34
|
+
timestamp: number;
|
|
35
|
+
tool_name?: string;
|
|
36
|
+
command?: string;
|
|
37
|
+
args?: Record<string, any>;
|
|
38
|
+
output?: any;
|
|
39
|
+
file_path?: string;
|
|
40
|
+
cwd?: string;
|
|
41
|
+
env?: Record<string, string>;
|
|
42
|
+
agent_id?: string;
|
|
43
|
+
metadata?: Record<string, any>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface HookResult {
|
|
47
|
+
event_id: string;
|
|
48
|
+
verdict: HookVerdict;
|
|
49
|
+
message: string;
|
|
50
|
+
exit_code: number;
|
|
51
|
+
mutated_input?: Record<string, any>;
|
|
52
|
+
mutated_command?: string;
|
|
53
|
+
rule_id?: string;
|
|
54
|
+
metadata?: Record<string, any>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PolicyRule {
|
|
58
|
+
rule_id: string;
|
|
59
|
+
description: string;
|
|
60
|
+
evaluate(event: HookEvent): HookResult | null;
|
|
61
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgenticWorkflow — Universal Autonomous Agentic Toolchain
|
|
3
|
+
* TypeScript Declaration File
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export * from './engine_ts/types.js';
|
|
7
|
+
export * from './engine_ts/event-bus.js';
|
|
8
|
+
export * from './engine_ts/queue.js';
|
|
9
|
+
export * from './engine_ts/decider.js';
|
|
10
|
+
export * from './engine_ts/verification-controller.js';
|
|
11
|
+
export * from './engine_ts/worker.js';
|
|
12
|
+
export * from './engine_ts/executor.js';
|
|
13
|
+
export * from './engine_ts/skills-indexer.js';
|
|
14
|
+
export * from './engine_ts/toon-adapter.js';
|
|
15
|
+
|
|
16
|
+
export * from './hooks/types.js';
|
|
17
|
+
export * from './hooks/dispatcher.js';
|
|
18
|
+
export * from './hooks/session-end.js';
|
|
19
|
+
export * from './hooks/policy-engine.js';
|
|
20
|
+
|
|
21
|
+
export * from './integrations/registry.js';
|
|
22
|
+
export * from './integrations/installer.js';
|
|
23
|
+
export * from './integrations/lifecycle-director.js';
|
|
24
|
+
|
|
25
|
+
export * from './system/types.js';
|
|
26
|
+
export * from './system/updater.js';
|
|
27
|
+
export * from './system/installer.js';
|
|
28
|
+
export * from './system/refresher.js';
|
|
29
|
+
export * from './system/doctor.js';
|
|
30
|
+
export * from './system/health.js';
|
|
31
|
+
export * from './system/dependencies.js';
|
|
32
|
+
export * from './system/notifications.js';
|
|
33
|
+
export * from './system/announcements.js';
|
|
34
|
+
export * from './system/version-tracker.js';
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgenticWorkflow — Universal Autonomous Agentic Toolchain & Pluripotent Stem-Cell Framework
|
|
3
|
+
*
|
|
4
|
+
* Top-level exports for TypeScript, Bun, and Node library consumers.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Event-driven engine, task queue, circuit breaker, verification controller
|
|
8
|
+
export * from './engine_ts/index.js';
|
|
9
|
+
|
|
10
|
+
// Universal Agentic Hooks Framework (UAHF)
|
|
11
|
+
export * from './hooks/index.js';
|
|
12
|
+
|
|
13
|
+
// Supportive Tools Subsystem (Ponytail, TOON, Fable, Caveman, LifecycleDirector)
|
|
14
|
+
export * from './integrations/index.js';
|
|
15
|
+
|
|
16
|
+
// Token-Oriented Object Notation (TOON v4.1) Adapter
|
|
17
|
+
export * from './engine_ts/toon-adapter.js';
|
|
18
|
+
|
|
19
|
+
// Agentic Skills Mesh & Universal Indexer
|
|
20
|
+
export * from './engine_ts/skills-indexer.js';
|
|
21
|
+
|
|
22
|
+
// Universal System Engines (Updater, Installer, Refresher, Doctor, Health, Dependencies, Notifications, Announcements, Version Tracker)
|
|
23
|
+
export * from './system/index.ts';
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* installer.ts — TypeScript/Bun Autonomous Supportive Tools Provisioner
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import { IntegrationDefinition, IntegrationsRegistry, getDefaultRegistry } from './registry.ts';
|
|
10
|
+
|
|
11
|
+
export interface InstallationStatus {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
installed: boolean;
|
|
15
|
+
status: 'INSTALLED' | 'MISSING' | 'ERROR' | 'PROVISIONED';
|
|
16
|
+
details: string;
|
|
17
|
+
locations: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class IntegrationInstaller {
|
|
21
|
+
private projectDir: string;
|
|
22
|
+
private homeDir: string;
|
|
23
|
+
private targetSkillDirs: string[];
|
|
24
|
+
|
|
25
|
+
constructor(projectDir: string = '.') {
|
|
26
|
+
this.projectDir = path.resolve(projectDir);
|
|
27
|
+
this.homeDir = os.homedir();
|
|
28
|
+
this.targetSkillDirs = [
|
|
29
|
+
path.join(this.homeDir, '.gemini', 'config', 'skills'),
|
|
30
|
+
path.join(this.homeDir, '.claude', 'skills'),
|
|
31
|
+
path.join(this.homeDir, '.agents', 'skills'),
|
|
32
|
+
path.join(this.homeDir, '.codex', 'skills'),
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private findExistingSkillDir(skillName: string): string | null {
|
|
37
|
+
const searchDirs = [
|
|
38
|
+
...this.targetSkillDirs,
|
|
39
|
+
path.join(this.homeDir, '.agent-kernel', 'plugins', skillName, 'skills', skillName),
|
|
40
|
+
path.join(this.homeDir, '.agent-kernel', 'plugins', skillName, 'skills'),
|
|
41
|
+
path.join(this.homeDir, '.claude', 'plugins', 'marketplaces', skillName),
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
for (const dir of searchDirs) {
|
|
45
|
+
if (fs.existsSync(dir) && fs.statSync(dir).isDirectory()) {
|
|
46
|
+
const skillFile = path.join(dir, 'SKILL.md');
|
|
47
|
+
if (fs.existsSync(skillFile)) {
|
|
48
|
+
return dir;
|
|
49
|
+
}
|
|
50
|
+
const childDir = path.join(dir, skillName);
|
|
51
|
+
if (fs.existsSync(childDir) && fs.existsSync(path.join(childDir, 'SKILL.md'))) {
|
|
52
|
+
return childDir;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public checkStatus(item: IntegrationDefinition): InstallationStatus {
|
|
60
|
+
const detectedLocations: string[] = [];
|
|
61
|
+
|
|
62
|
+
// 1. Skill directories
|
|
63
|
+
const skillNames: string[] = item.install?.skill_names || [item.id];
|
|
64
|
+
for (const sname of skillNames) {
|
|
65
|
+
for (const base of this.targetSkillDirs) {
|
|
66
|
+
const candidate = path.join(base, sname);
|
|
67
|
+
if (fs.existsSync(candidate)) {
|
|
68
|
+
detectedLocations.push(candidate);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 2. npm / bun package
|
|
74
|
+
const npmPkg = item.detection?.npm_package;
|
|
75
|
+
if (npmPkg) {
|
|
76
|
+
const pkgPath = path.join(this.projectDir, 'node_modules', npmPkg);
|
|
77
|
+
if (fs.existsSync(pkgPath)) {
|
|
78
|
+
detectedLocations.push(`node_modules/${npmPkg}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 3. state dir
|
|
83
|
+
const stateDir = item.detection?.state_dir;
|
|
84
|
+
if (stateDir) {
|
|
85
|
+
const fullState = path.join(this.projectDir, stateDir);
|
|
86
|
+
if (fs.existsSync(fullState)) {
|
|
87
|
+
detectedLocations.push(stateDir);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const isInstalled = detectedLocations.length > 0;
|
|
92
|
+
return {
|
|
93
|
+
id: item.id,
|
|
94
|
+
name: item.name,
|
|
95
|
+
installed: isInstalled,
|
|
96
|
+
status: isInstalled ? 'INSTALLED' : 'MISSING',
|
|
97
|
+
details: isInstalled ? `Active at ${detectedLocations.length} location(s)` : 'Not found in environment paths',
|
|
98
|
+
locations: detectedLocations
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public provision(item: IntegrationDefinition, synchronizeAll: boolean = true): InstallationStatus {
|
|
103
|
+
const strategy = item.install?.strategy || 'skill';
|
|
104
|
+
const createdLocations: string[] = [];
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
if (strategy === 'skill' || strategy === 'hybrid') {
|
|
108
|
+
const skillNames: string[] = item.install?.skill_names || [item.id];
|
|
109
|
+
for (const sname of skillNames) {
|
|
110
|
+
const existing = this.findExistingSkillDir(sname);
|
|
111
|
+
if (existing) {
|
|
112
|
+
for (const targetDir of this.targetSkillDirs) {
|
|
113
|
+
const dest = path.join(targetDir, sname);
|
|
114
|
+
if (!fs.existsSync(dest)) {
|
|
115
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
116
|
+
try {
|
|
117
|
+
fs.symlinkSync(existing, dest);
|
|
118
|
+
createdLocations.push(dest);
|
|
119
|
+
} catch {
|
|
120
|
+
fs.cpSync(existing, dest, { recursive: true });
|
|
121
|
+
createdLocations.push(dest);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
const fallbackGit = item.install?.fallback_git;
|
|
127
|
+
if (fallbackGit) {
|
|
128
|
+
const primaryTarget = path.join(this.homeDir, '.agents', 'skills', sname);
|
|
129
|
+
fs.mkdirSync(path.dirname(primaryTarget), { recursive: true });
|
|
130
|
+
try {
|
|
131
|
+
execSync(`git clone --depth 1 "${fallbackGit}" "${primaryTarget}"`, { stdio: 'pipe', timeout: 30000 });
|
|
132
|
+
createdLocations.push(primaryTarget);
|
|
133
|
+
for (const targetDir of this.targetSkillDirs) {
|
|
134
|
+
const dest = path.join(targetDir, sname);
|
|
135
|
+
if (!fs.existsSync(dest)) {
|
|
136
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
137
|
+
try {
|
|
138
|
+
fs.symlinkSync(primaryTarget, dest);
|
|
139
|
+
createdLocations.push(dest);
|
|
140
|
+
} catch {
|
|
141
|
+
fs.cpSync(primaryTarget, dest, { recursive: true });
|
|
142
|
+
createdLocations.push(dest);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// Ignore clone errors
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (strategy === 'package' || strategy === 'hybrid') {
|
|
155
|
+
const bunPkg = item.install?.bun_package;
|
|
156
|
+
const npmPkg = item.detection?.npm_package;
|
|
157
|
+
if (bunPkg && (!npmPkg || !fs.existsSync(path.join(this.projectDir, 'node_modules', npmPkg)))) {
|
|
158
|
+
try {
|
|
159
|
+
execSync(`bun add "${bunPkg}"`, { cwd: this.projectDir, stdio: 'pipe', timeout: 30000 });
|
|
160
|
+
createdLocations.push(`bun:${bunPkg}`);
|
|
161
|
+
} catch {
|
|
162
|
+
// Ignore if bun fails
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const postStatus = this.checkStatus(item);
|
|
168
|
+
if (postStatus.installed || createdLocations.length > 0) {
|
|
169
|
+
return {
|
|
170
|
+
id: item.id,
|
|
171
|
+
name: item.name,
|
|
172
|
+
installed: true,
|
|
173
|
+
status: createdLocations.length > 0 ? 'PROVISIONED' : postStatus.status,
|
|
174
|
+
details: `Active at ${postStatus.locations.length} location(s)` + (createdLocations.length > 0 ? ` (${createdLocations.length} newly synced)` : ''),
|
|
175
|
+
locations: postStatus.locations
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
id: item.id,
|
|
181
|
+
name: item.name,
|
|
182
|
+
installed: false,
|
|
183
|
+
status: 'ERROR',
|
|
184
|
+
details: 'Provisioning completed without active targets confirmed',
|
|
185
|
+
locations: []
|
|
186
|
+
};
|
|
187
|
+
} catch (err: any) {
|
|
188
|
+
return {
|
|
189
|
+
id: item.id,
|
|
190
|
+
name: item.name,
|
|
191
|
+
installed: false,
|
|
192
|
+
status: 'ERROR',
|
|
193
|
+
details: `Provisioning error: ${err?.message || String(err)}`,
|
|
194
|
+
locations: []
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public provisionAll(registry?: IntegrationsRegistry): InstallationStatus[] {
|
|
200
|
+
const reg = registry || getDefaultRegistry(this.projectDir);
|
|
201
|
+
return reg.listAll().map(item => this.provision(item, true));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public checkAll(registry?: IntegrationsRegistry): InstallationStatus[] {
|
|
205
|
+
const reg = registry || getDefaultRegistry(this.projectDir);
|
|
206
|
+
return reg.listAll().map(item => this.checkStatus(item));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lifecycle-director.ts — TypeScript Sequential Operational Lifecycle Director
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { IntegrationsRegistry, getDefaultRegistry } from './registry.ts';
|
|
8
|
+
|
|
9
|
+
export interface PhaseDirectives {
|
|
10
|
+
phase: string;
|
|
11
|
+
activeIntegrations: string[];
|
|
12
|
+
systemPromptOverlay: string;
|
|
13
|
+
rules: string[];
|
|
14
|
+
toolsEngaged: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class LifecycleDirector {
|
|
18
|
+
private projectDir: string;
|
|
19
|
+
private registry: IntegrationsRegistry;
|
|
20
|
+
|
|
21
|
+
constructor(projectDir: string = '.', registry?: IntegrationsRegistry) {
|
|
22
|
+
this.projectDir = path.resolve(projectDir);
|
|
23
|
+
this.registry = registry || getDefaultRegistry(this.projectDir);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public getPhaseDirectives(phase: string): PhaseDirectives {
|
|
27
|
+
const norm = phase.toLowerCase().trim();
|
|
28
|
+
const matched = this.registry.getForPhase(norm);
|
|
29
|
+
|
|
30
|
+
const activeNames = matched.map(m => m.name);
|
|
31
|
+
const toolsEngaged = matched.map(m => m.id);
|
|
32
|
+
const rules: string[] = [];
|
|
33
|
+
const sections: string[] = [];
|
|
34
|
+
|
|
35
|
+
// Continuous protocols (TOON & Caveman)
|
|
36
|
+
const toonItem = this.registry.get('toon');
|
|
37
|
+
if (toonItem && toonItem.directives?.continuous) {
|
|
38
|
+
sections.push(`### [Continuous Protocol] TOON v4.1 Serialization\n${toonItem.directives.continuous}`);
|
|
39
|
+
rules.push('Format all structured datasets and task tables in TOON syntax to conserve 30-60% tokens.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const cavemanItem = this.registry.get('caveman');
|
|
43
|
+
if (cavemanItem && cavemanItem.directives?.continuous) {
|
|
44
|
+
sections.push(`### [Communication Protocol] Caveman Terse Mode\n${cavemanItem.directives.continuous}`);
|
|
45
|
+
rules.push('Eliminate pleasantries in logs and intermediate agent thought; keep code, paths, and errors verbatim.');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const item of matched) {
|
|
49
|
+
if (item.directives?.[norm]) {
|
|
50
|
+
sections.push(`### [${item.name}] Phase Directives (${norm})\n${item.directives[norm]}`);
|
|
51
|
+
rules.push(`[${item.name}] ${item.directives[norm]}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let overview = `## ⚡ Sequential Lifecycle Directive: ${norm.toUpperCase()} Phase`;
|
|
56
|
+
if (norm === 'planning') {
|
|
57
|
+
overview = `## 🧭 Sequential Lifecycle Directive: Phase 2 — Architecture & Planning
|
|
58
|
+
Enforce Ponytail YAGNI Ladder (Rungs 1-3):
|
|
59
|
+
1. Question whether every proposed component needs to exist.
|
|
60
|
+
2. Reuse existing helpers and stdlib before creating new abstractions.
|
|
61
|
+
3. Formulate verifiable Fable contracts with concrete success criteria.
|
|
62
|
+
4. Compile and validate OmniSkill SkillSpec contracts and dynamic DAG execution paths.`;
|
|
63
|
+
} else if (norm === 'implementation') {
|
|
64
|
+
overview = `## 🔨 Sequential Lifecycle Directive: Phase 3 — Production Implementation
|
|
65
|
+
1. Shortest working diff wins. Minimum code that works (Ponytail Rungs 4-7).
|
|
66
|
+
2. Fix root causes across callers/callees, not symptoms.
|
|
67
|
+
3. Fable Circuit Breaker active: halt speculative edits if failure streak >= 2.
|
|
68
|
+
4. Follow OmniSkill progressive disclosure: frontmatter <=1024 chars, core SKILL.md, references/, scripts/.`;
|
|
69
|
+
} else if (norm === 'verification') {
|
|
70
|
+
overview = `## 🛡️ Sequential Lifecycle Directive: Phase 4 — Verification & Quality Gates
|
|
71
|
+
1. Run Clean Code Guard (SOLID, 24 Imperatives).
|
|
72
|
+
2. Perform Ponytail anti-debt check against over-engineering.
|
|
73
|
+
3. Pass L0 Anti-Skip, L1 Verification, L1.5 pACS (min score >= 70), and L2 Review.
|
|
74
|
+
4. Enforce OmniSkill 4-Layer Validation (Artifact, Discovery, Behavior, Portability).`;
|
|
75
|
+
} else if (norm === 'handoff') {
|
|
76
|
+
overview = `## 🏁 Sequential Lifecycle Directive: Phase 5 — Handoff & Continuation
|
|
77
|
+
1. Compact session into durable continuation state (.fable/state.json, PROGRESS.md).
|
|
78
|
+
2. Archive run traces and ledgers in high-density TOON format.`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const systemPromptOverlay = `${overview}\n\n` + sections.join('\n\n');
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
phase: norm,
|
|
85
|
+
activeIntegrations: activeNames,
|
|
86
|
+
systemPromptOverlay,
|
|
87
|
+
rules,
|
|
88
|
+
toolsEngaged
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public executePrePhaseGuards(phase: string, context: Record<string, any> = {}): { allowed: boolean; warnings: string[]; actionsTaken: string[] } {
|
|
93
|
+
const norm = phase.toLowerCase().trim();
|
|
94
|
+
const warnings: string[] = [];
|
|
95
|
+
const actionsTaken: string[] = [];
|
|
96
|
+
let allowed = true;
|
|
97
|
+
|
|
98
|
+
if (norm === 'implementation') {
|
|
99
|
+
const streak = context.failure_streak || 0;
|
|
100
|
+
if (streak >= 2) {
|
|
101
|
+
allowed = false;
|
|
102
|
+
warnings.push(`Fable Circuit Breaker TRIPPED: failure streak (${streak}) >= 2. Halting to prevent thrashing.`);
|
|
103
|
+
actionsTaken.push('trip_circuit_breaker');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (norm === 'planning') {
|
|
108
|
+
actionsTaken.push('enforce_ponytail_yagni_gate');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { allowed, warnings, actionsTaken };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public executePostPhaseActions(phase: string, context: Record<string, any> = {}): { success: boolean; artifactsGenerated: string[] } {
|
|
115
|
+
const norm = phase.toLowerCase().trim();
|
|
116
|
+
const artifactsGenerated: string[] = [];
|
|
117
|
+
|
|
118
|
+
if (norm === 'handoff') {
|
|
119
|
+
const fableDir = path.join(this.projectDir, '.fable');
|
|
120
|
+
fs.mkdirSync(fableDir, { recursive: true });
|
|
121
|
+
const stateFile = path.join(fableDir, 'state.json');
|
|
122
|
+
const progressFile = path.join(fableDir, 'PROGRESS.md');
|
|
123
|
+
|
|
124
|
+
const payload = {
|
|
125
|
+
trace_id: context.trace_id || `trace_${Date.now()}`,
|
|
126
|
+
timestamp: new Date().toISOString(),
|
|
127
|
+
status: 'COMPLETED',
|
|
128
|
+
next_action: context.next_action || 'All workflow stages verified cleanly.'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
fs.writeFileSync(stateFile, JSON.stringify(payload, null, 2), 'utf-8');
|
|
132
|
+
fs.writeFileSync(progressFile, `# Fable Continuation Progress\n\n- Timestamp: ${payload.timestamp}\n- Trace: \`${payload.trace_id}\`\n- Next Action: ${payload.next_action}\n`, 'utf-8');
|
|
133
|
+
|
|
134
|
+
artifactsGenerated.push(stateFile, progressFile);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { success: true, artifactsGenerated };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* registry.ts — TypeScript Integrations Registry & Manifest Manager
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
|
|
8
|
+
export interface IntegrationDefinition {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
repo: string;
|
|
12
|
+
description: string;
|
|
13
|
+
category: string;
|
|
14
|
+
lifecycle_phases: string[];
|
|
15
|
+
install: Record<string, any>;
|
|
16
|
+
detection: Record<string, any>;
|
|
17
|
+
directives: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class IntegrationsRegistry {
|
|
21
|
+
private integrations: Map<string, IntegrationDefinition> = new Map();
|
|
22
|
+
private manifestPath: string | null = null;
|
|
23
|
+
|
|
24
|
+
constructor(manifestPath?: string) {
|
|
25
|
+
if (manifestPath && fs.existsSync(manifestPath)) {
|
|
26
|
+
this.loadFromFile(manifestPath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public loadFromFile(filePath: string): void {
|
|
31
|
+
this.manifestPath = path.resolve(filePath);
|
|
32
|
+
const content = fs.readFileSync(this.manifestPath, 'utf-8');
|
|
33
|
+
const data = JSON.parse(content);
|
|
34
|
+
this.integrations.clear();
|
|
35
|
+
for (const item of data.integrations || []) {
|
|
36
|
+
this.integrations.set(item.id, item);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public saveToFile(targetPath?: string): void {
|
|
41
|
+
const dest = targetPath || this.manifestPath;
|
|
42
|
+
if (!dest) {
|
|
43
|
+
throw new Error("No target path specified for saving integrations manifest.");
|
|
44
|
+
}
|
|
45
|
+
const data = {
|
|
46
|
+
version: "1.0.0",
|
|
47
|
+
description: "Declarative registry of supportive tools, frameworks, and agentic skills for AgenticWorkflow",
|
|
48
|
+
integrations: Array.from(this.integrations.values())
|
|
49
|
+
};
|
|
50
|
+
fs.writeFileSync(dest, JSON.stringify(data, null, 2), 'utf-8');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public register(item: IntegrationDefinition): void {
|
|
54
|
+
this.integrations.set(item.id, item);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public get(id: string): IntegrationDefinition | undefined {
|
|
58
|
+
return this.integrations.get(id);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public listAll(): IntegrationDefinition[] {
|
|
62
|
+
return Array.from(this.integrations.values());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public getForPhase(phase: string): IntegrationDefinition[] {
|
|
66
|
+
const norm = phase.toLowerCase().trim();
|
|
67
|
+
return this.listAll().filter(item =>
|
|
68
|
+
item.lifecycle_phases.includes("continuous") || item.lifecycle_phases.includes(norm)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getDefaultRegistry(projectDir: string = "."): IntegrationsRegistry {
|
|
74
|
+
let manifestPath = path.join(path.resolve(projectDir), "integrations.json");
|
|
75
|
+
if (!fs.existsSync(manifestPath)) {
|
|
76
|
+
const rootFallback = path.resolve(__dirname, "..", "..", "integrations.json");
|
|
77
|
+
if (fs.existsSync(rootFallback)) {
|
|
78
|
+
manifestPath = rootFallback;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return new IntegrationsRegistry(manifestPath);
|
|
82
|
+
}
|