@evo-dev/core 0.0.1-alpha

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 (51) hide show
  1. package/assets/agents/review/code-reviewer/examples.md +19 -0
  2. package/assets/agents/review/code-reviewer/manifest.json +10 -0
  3. package/assets/agents/review/code-reviewer/prompt.md +59 -0
  4. package/assets/agents/review/code-reviewer/verification.md +11 -0
  5. package/assets/skills/coding/engineering-discipline/SKILL.md +63 -0
  6. package/assets/skills/coding/engineering-discipline/anti-patterns.md +21 -0
  7. package/assets/skills/coding/engineering-discipline/examples.md +19 -0
  8. package/assets/skills/coding/engineering-discipline/manifest.json +10 -0
  9. package/assets/skills/coding/engineering-discipline/verification.md +11 -0
  10. package/assets/workflows/rd-bug-fix/WORKFLOW.json +45 -0
  11. package/assets/workflows/rd-code-review/WORKFLOW.json +45 -0
  12. package/assets/workflows/rd-docs-update/WORKFLOW.json +45 -0
  13. package/assets/workflows/rd-feature-implementation/WORKFLOW.json +45 -0
  14. package/assets/workflows/rd-refactor/WORKFLOW.json +45 -0
  15. package/assets/workflows/rd-release-readiness/WORKFLOW.json +49 -0
  16. package/assets/workflows/rd-security-boundary-review/WORKFLOW.json +45 -0
  17. package/assets/workflows/rd-test-generation/WORKFLOW.json +45 -0
  18. package/dist/assets/index.js +209 -0
  19. package/dist/config/index.js +601 -0
  20. package/dist/index.js +4879 -0
  21. package/dist/plugins/index.js +265 -0
  22. package/package.json +30 -0
  23. package/src/.gitkeep +0 -0
  24. package/src/agents/index.ts +561 -0
  25. package/src/assets/errors.ts +21 -0
  26. package/src/assets/index.ts +18 -0
  27. package/src/assets/manifest.ts +109 -0
  28. package/src/assets/scanner.ts +189 -0
  29. package/src/config/errors.ts +21 -0
  30. package/src/config/index.ts +26 -0
  31. package/src/config/paths.ts +43 -0
  32. package/src/config/registry.ts +84 -0
  33. package/src/config/settings.ts +212 -0
  34. package/src/config/state.ts +130 -0
  35. package/src/config/store.ts +166 -0
  36. package/src/daemon/index.ts +414 -0
  37. package/src/hooks/index.ts +1023 -0
  38. package/src/index.ts +14 -0
  39. package/src/learning/index.ts +714 -0
  40. package/src/observability/index.ts +272 -0
  41. package/src/pack/index.ts +779 -0
  42. package/src/plugins/capabilities.ts +347 -0
  43. package/src/plugins/index.ts +41 -0
  44. package/src/plugins/registry.ts +60 -0
  45. package/src/plugins/types.ts +123 -0
  46. package/src/project/index.ts +507 -0
  47. package/src/protected-zones/index.ts +137 -0
  48. package/src/sync/index.ts +7 -0
  49. package/src/sync/orchestrator.ts +298 -0
  50. package/src/task/index.ts +840 -0
  51. package/src/workflow/index.ts +137 -0
@@ -0,0 +1,265 @@
1
+ // packages/core/src/plugins/capabilities.ts
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ function createUnknownNegotiatedCapabilities(pluginId) {
5
+ return {
6
+ pluginId,
7
+ skills: "unsupported",
8
+ agents: "unsupported",
9
+ hooks: "unsupported",
10
+ canPlanWrites: false,
11
+ warnings: [],
12
+ blockers: [`Plugin ${pluginId} capabilities are unknown and unsupported.`]
13
+ };
14
+ }
15
+ function isCapabilityUsable(state) {
16
+ return state === "enabled";
17
+ }
18
+ function assertNoUnverifiedWrites(negotiation) {
19
+ if (!negotiation.canPlanWrites) {
20
+ throw new Error(`Plugin ${negotiation.pluginId} has no verified enabled write capabilities.`);
21
+ }
22
+ }
23
+ function negotiatePluginCapabilities(input) {
24
+ if (input.pluginId === "codex") {
25
+ const declaredSupport = [
26
+ input.declared.skills.supported ? "skills" : null,
27
+ input.declared.agents.supported ? "agents" : null,
28
+ input.declared.hooks.supported ? "hooks" : null
29
+ ].filter(Boolean);
30
+ const blockers = ["Codex capabilities are unverified; writes are unsupported in I10."];
31
+ const warnings = [
32
+ input.verified ? "Codex readonly verification artifact exists; sync remains no-write until formats are verified." : null,
33
+ declaredSupport.length > 0 ? `Codex declares ${declaredSupport.join(", ")} support, but declared support alone cannot authorize writes.` : null
34
+ ].filter((warning) => warning !== null);
35
+ return {
36
+ pluginId: input.pluginId,
37
+ skills: input.declared.skills.supported ? "unverified" : "unsupported",
38
+ agents: input.declared.agents.supported ? "unverified" : "unsupported",
39
+ hooks: input.declared.hooks.supported ? "unverified" : "unsupported",
40
+ canPlanWrites: false,
41
+ warnings,
42
+ blockers
43
+ };
44
+ }
45
+ return {
46
+ pluginId: input.pluginId,
47
+ skills: resolveNonCodexCapabilityState(input.declared.skills.supported, input.enabled),
48
+ agents: resolveNonCodexCapabilityState(input.declared.agents.supported, input.enabled),
49
+ hooks: resolveNonCodexCapabilityState(input.declared.hooks.supported, input.enabled),
50
+ canPlanWrites: input.enabled && input.declared.skills.supported && input.declared.agents.supported,
51
+ warnings: input.enabled ? [] : [
52
+ `Plugin ${input.pluginId} has declared capabilities but is not enabled; writes are not authorized.`
53
+ ],
54
+ blockers: []
55
+ };
56
+ }
57
+ function resolveNonCodexCapabilityState(supported, enabled) {
58
+ if (!supported)
59
+ return "unsupported";
60
+ return enabled ? "enabled" : "declared";
61
+ }
62
+ async function createCodexCapabilityVerificationArtifact(input) {
63
+ const timestamp = input.createdAt ?? new Date().toISOString();
64
+ const detectionMessage = sanitizeText(input.detection.message);
65
+ const diagnostics = [
66
+ "Codex remains no-write until concrete user-level paths and formats are verified."
67
+ ];
68
+ return {
69
+ version: 1,
70
+ pluginId: "codex",
71
+ status: "verified-readonly",
72
+ verifiedAt: timestamp,
73
+ createdAt: timestamp,
74
+ metadataOnly: true,
75
+ rawOutputStored: false,
76
+ sourceContentStored: false,
77
+ promptHistoryStored: false,
78
+ promptStored: false,
79
+ secretsStored: false,
80
+ externalUpload: false,
81
+ networkUsed: false,
82
+ toolSummary: { tool: "codex", detectionStatus: input.detection.status, version: null },
83
+ capabilities: { skills: "unverified", agents: "unverified", hooks: "unverified" },
84
+ writeBoundary: {
85
+ writesAllowed: false,
86
+ allowedPaths: [],
87
+ userLevelOnly: true,
88
+ noOverwrite: true,
89
+ projectWritesAllowed: false,
90
+ codeAgentWritesAllowed: false
91
+ },
92
+ privacy: {
93
+ classification: "local-private",
94
+ metadataOnly: true,
95
+ rawOutputStored: false,
96
+ sourceContentStored: false,
97
+ promptHistoryStored: false,
98
+ secretsStored: false,
99
+ externalUpload: false
100
+ },
101
+ blockers: ["Codex asset capabilities are unverified and unsupported for writes in I10."],
102
+ diagnostics,
103
+ evidenceRefs: [],
104
+ evidence: {
105
+ detectionStatus: input.detection.status,
106
+ detectionMessage,
107
+ writesAllowed: false,
108
+ notes: [
109
+ "Metadata-only readonly artifact; no Codex paths, formats, hooks, or writes verified."
110
+ ]
111
+ }
112
+ };
113
+ }
114
+ function resolveCodexCapabilityArtifactPath(homeDir) {
115
+ return join(homeDir, ".evodev", "STATE", "plugins", "codex", "capability-verification.json");
116
+ }
117
+ async function writeCodexCapabilityVerificationArtifact(homeDir, artifact) {
118
+ validateCodexCapabilityVerificationArtifact(artifact);
119
+ const path = resolveCodexCapabilityArtifactPath(homeDir);
120
+ await mkdir(dirname(path), { recursive: true });
121
+ await writeFile(path, `${JSON.stringify(artifact, null, 2)}
122
+ `, { encoding: "utf8", flag: "wx" });
123
+ return path;
124
+ }
125
+ async function readCodexCapabilityVerificationArtifact(homeDir) {
126
+ try {
127
+ const artifact = JSON.parse(await readFile(resolveCodexCapabilityArtifactPath(homeDir), "utf8"));
128
+ validateCodexCapabilityVerificationArtifact(artifact);
129
+ return artifact;
130
+ } catch (error) {
131
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
132
+ return null;
133
+ }
134
+ throw error;
135
+ }
136
+ }
137
+ function validateCodexCapabilityVerificationArtifact(artifact) {
138
+ if (artifact.version !== 1 || artifact.pluginId !== "codex")
139
+ throw new Error("Invalid Codex artifact identity.");
140
+ if (artifact.metadataOnly !== true || artifact.rawOutputStored !== false || artifact.sourceContentStored !== false || artifact.promptStored !== false || artifact.promptHistoryStored !== false || artifact.secretsStored !== false || artifact.externalUpload !== false || artifact.networkUsed !== false || artifact.privacy?.metadataOnly !== true || artifact.privacy.rawOutputStored !== false || artifact.privacy.sourceContentStored !== false || artifact.privacy.promptHistoryStored !== false || artifact.privacy.secretsStored !== false || artifact.privacy.externalUpload !== false || artifact.writeBoundary?.writesAllowed !== false || artifact.writeBoundary.allowedPaths.length !== 0 || artifact.writeBoundary.userLevelOnly !== true || artifact.writeBoundary.noOverwrite !== true || artifact.writeBoundary.projectWritesAllowed !== false || artifact.writeBoundary.codeAgentWritesAllowed !== false) {
141
+ throw new Error("Codex artifact must be metadata-only and local-only.");
142
+ }
143
+ assertNoSensitiveContent(artifact);
144
+ }
145
+ function formatCodexCapabilityVerificationArtifact(artifact, path) {
146
+ return [
147
+ "EvoDev Codex capability verification",
148
+ "",
149
+ `Status: ${artifact.status}`,
150
+ `Artifact: ${path ?? "dry-run only"}`,
151
+ `Verified at: ${artifact.verifiedAt}`,
152
+ "Capabilities: skills=unverified agents=unverified hooks=unverified",
153
+ "Writes allowed: false",
154
+ "Allowed paths: none",
155
+ "User-level write paths verified: false",
156
+ "Project writes allowed: false",
157
+ "No-overwrite verified: false",
158
+ `External upload: ${artifact.externalUpload}`,
159
+ `Detection: ${artifact.evidence.detectionStatus}`,
160
+ ...artifact.evidence.notes.map((note) => `Note: ${note}`)
161
+ ].join(`
162
+ `);
163
+ }
164
+ async function runPluginConformance(plugin) {
165
+ const findings = [];
166
+ try {
167
+ await plugin.detect();
168
+ await plugin.getCapabilities();
169
+ } catch (error) {
170
+ findings.push(`Plugin ${plugin.id} threw during detect/capabilities: ${error instanceof Error ? error.message : String(error)}`);
171
+ }
172
+ if (plugin.id === "codex") {
173
+ const capabilities = await plugin.getCapabilities();
174
+ if (capabilities.skills.supported || capabilities.agents.supported || capabilities.hooks.supported) {
175
+ findings.push("Codex must not declare verified runtime support in I10.");
176
+ }
177
+ }
178
+ return { ok: findings.length === 0, findings };
179
+ }
180
+ function sanitizeText(value) {
181
+ return value.replace(/https?:\/\/\S+|\b(secret|token|password|private|internal|api[_-]?key)\b/gi, "[redacted]").slice(0, 300);
182
+ }
183
+ function assertNoSensitiveContent(value) {
184
+ if (typeof value === "string") {
185
+ if (value === "local-private")
186
+ return;
187
+ if (/https?:\/\/\S+|\b(secret|token|password|private|internal|api[_-]?key|raw output|raw source|raw prompt)\b/i.test(value)) {
188
+ throw new Error("Codex artifact contains sensitive content.");
189
+ }
190
+ return;
191
+ }
192
+ if (Array.isArray(value)) {
193
+ for (const item of value)
194
+ assertNoSensitiveContent(item);
195
+ return;
196
+ }
197
+ if (typeof value !== "object" || value === null)
198
+ return;
199
+ for (const [key, child] of Object.entries(value)) {
200
+ if (/raw|prompt|source|secret|token|password|memorybody/i.test(key) && child !== false) {
201
+ throw new Error(`Codex artifact contains forbidden field: ${key}`);
202
+ }
203
+ assertNoSensitiveContent(child);
204
+ }
205
+ }
206
+ // packages/core/src/plugins/registry.ts
207
+ class PluginRegistryError extends Error {
208
+ constructor(message) {
209
+ super(message);
210
+ this.name = "PluginRegistryError";
211
+ }
212
+ }
213
+
214
+ class PluginRegistry {
215
+ #plugins = new Map;
216
+ register(plugin) {
217
+ if (this.#plugins.has(plugin.id)) {
218
+ throw new PluginRegistryError(`Plugin already registered: ${plugin.id}`);
219
+ }
220
+ this.#plugins.set(plugin.id, plugin);
221
+ }
222
+ get(pluginId) {
223
+ return this.#plugins.get(pluginId);
224
+ }
225
+ require(pluginId) {
226
+ const plugin = this.get(pluginId);
227
+ if (plugin === undefined) {
228
+ throw new PluginRegistryError(`Plugin not registered: ${pluginId}`);
229
+ }
230
+ return plugin;
231
+ }
232
+ list() {
233
+ return [...this.#plugins.values()].sort((left, right) => left.id.localeCompare(right.id));
234
+ }
235
+ getEnabled(settings) {
236
+ return getEnabledPluginIds(settings).map((pluginId) => this.require(pluginId));
237
+ }
238
+ }
239
+ function createPluginRegistry(plugins = []) {
240
+ const registry = new PluginRegistry;
241
+ for (const plugin of plugins) {
242
+ registry.register(plugin);
243
+ }
244
+ return registry;
245
+ }
246
+ function getEnabledPluginIds(settings) {
247
+ return Object.entries(settings.plugins).filter(([, pluginSettings]) => pluginSettings.enabled).map(([pluginId]) => pluginId).sort((left, right) => left.localeCompare(right));
248
+ }
249
+ export {
250
+ writeCodexCapabilityVerificationArtifact,
251
+ validateCodexCapabilityVerificationArtifact,
252
+ runPluginConformance,
253
+ resolveCodexCapabilityArtifactPath,
254
+ readCodexCapabilityVerificationArtifact,
255
+ negotiatePluginCapabilities,
256
+ isCapabilityUsable,
257
+ getEnabledPluginIds,
258
+ formatCodexCapabilityVerificationArtifact,
259
+ createUnknownNegotiatedCapabilities,
260
+ createPluginRegistry,
261
+ createCodexCapabilityVerificationArtifact,
262
+ assertNoUnverifiedWrites,
263
+ PluginRegistryError,
264
+ PluginRegistry
265
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@evo-dev/core",
3
+ "version": "0.0.1-alpha",
4
+ "type": "module",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/limerickgds/evodev.git",
8
+ "directory": "packages/core"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./src/index.ts",
13
+ "import": "./dist/index.js"
14
+ },
15
+ "./assets": {
16
+ "types": "./src/assets/index.ts",
17
+ "import": "./dist/assets/index.js"
18
+ },
19
+ "./config": {
20
+ "types": "./src/config/index.ts",
21
+ "import": "./dist/config/index.js"
22
+ },
23
+ "./plugins": {
24
+ "types": "./src/plugins/index.ts",
25
+ "import": "./dist/plugins/index.js"
26
+ }
27
+ },
28
+ "files": ["dist", "src", "assets", "package.json"],
29
+ "license": "MIT"
30
+ }
package/src/.gitkeep ADDED
File without changes