loreli 0.0.0 → 2.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.
- package/LICENSE +1 -1
- package/README.md +710 -97
- package/bin/loreli.js +89 -0
- package/package.json +77 -14
- package/packages/README.md +101 -0
- package/packages/action/README.md +98 -0
- package/packages/action/prompts/action.md +172 -0
- package/packages/action/src/index.js +684 -0
- package/packages/agent/README.md +606 -0
- package/packages/agent/src/backends/claude.js +387 -0
- package/packages/agent/src/backends/codex.js +351 -0
- package/packages/agent/src/backends/cursor.js +371 -0
- package/packages/agent/src/backends/index.js +486 -0
- package/packages/agent/src/base.js +138 -0
- package/packages/agent/src/cli.js +275 -0
- package/packages/agent/src/discover.js +396 -0
- package/packages/agent/src/factory.js +124 -0
- package/packages/agent/src/index.js +12 -0
- package/packages/agent/src/models.js +159 -0
- package/packages/agent/src/output.js +62 -0
- package/packages/agent/src/session.js +162 -0
- package/packages/agent/src/trace.js +186 -0
- package/packages/classify/README.md +136 -0
- package/packages/classify/prompts/blocker.md +12 -0
- package/packages/classify/prompts/feedback.md +14 -0
- package/packages/classify/prompts/pane-state.md +20 -0
- package/packages/classify/src/index.js +81 -0
- package/packages/config/README.md +898 -0
- package/packages/config/src/defaults.js +145 -0
- package/packages/config/src/index.js +223 -0
- package/packages/config/src/schema.js +291 -0
- package/packages/config/src/validate.js +160 -0
- package/packages/context/README.md +165 -0
- package/packages/context/src/index.js +198 -0
- package/packages/hub/README.md +338 -0
- package/packages/hub/src/base.js +154 -0
- package/packages/hub/src/github.js +1597 -0
- package/packages/hub/src/index.js +79 -0
- package/packages/hub/src/labels.js +48 -0
- package/packages/identity/README.md +288 -0
- package/packages/identity/src/index.js +620 -0
- package/packages/identity/src/themes/avatar.js +217 -0
- package/packages/identity/src/themes/digimon.js +217 -0
- package/packages/identity/src/themes/dragonball.js +217 -0
- package/packages/identity/src/themes/lotr.js +217 -0
- package/packages/identity/src/themes/marvel.js +217 -0
- package/packages/identity/src/themes/pokemon.js +217 -0
- package/packages/identity/src/themes/starwars.js +217 -0
- package/packages/identity/src/themes/transformers.js +217 -0
- package/packages/identity/src/themes/zelda.js +217 -0
- package/packages/knowledge/README.md +217 -0
- package/packages/knowledge/src/index.js +243 -0
- package/packages/log/README.md +93 -0
- package/packages/log/src/index.js +252 -0
- package/packages/marker/README.md +200 -0
- package/packages/marker/src/index.js +184 -0
- package/packages/mcp/README.md +323 -0
- package/packages/mcp/instructions.md +126 -0
- package/packages/mcp/scaffolding/.agents/skills/loreli-context/SKILL.md +89 -0
- package/packages/mcp/scaffolding/ISSUE_TEMPLATE/config.yml +2 -0
- package/packages/mcp/scaffolding/ISSUE_TEMPLATE/loreli.yml +83 -0
- package/packages/mcp/scaffolding/loreli.yml +491 -0
- package/packages/mcp/scaffolding/mcp-configs/.codex/config.toml +4 -0
- package/packages/mcp/scaffolding/mcp-configs/.cursor/mcp.json +14 -0
- package/packages/mcp/scaffolding/mcp-configs/.mcp.json +14 -0
- package/packages/mcp/scaffolding/pull-request.md +23 -0
- package/packages/mcp/src/index.js +600 -0
- package/packages/mcp/src/tools/agent-context.js +44 -0
- package/packages/mcp/src/tools/agents.js +450 -0
- package/packages/mcp/src/tools/context.js +200 -0
- package/packages/mcp/src/tools/github.js +1163 -0
- package/packages/mcp/src/tools/hitl.js +162 -0
- package/packages/mcp/src/tools/index.js +18 -0
- package/packages/mcp/src/tools/refactor.js +227 -0
- package/packages/mcp/src/tools/repo.js +44 -0
- package/packages/mcp/src/tools/start.js +904 -0
- package/packages/mcp/src/tools/status.js +149 -0
- package/packages/mcp/src/tools/work.js +134 -0
- package/packages/orchestrator/README.md +192 -0
- package/packages/orchestrator/src/index.js +1492 -0
- package/packages/planner/README.md +251 -0
- package/packages/planner/prompts/plan-reviewer.md +109 -0
- package/packages/planner/prompts/planner.md +191 -0
- package/packages/planner/prompts/tiebreaker-reviewer.md +71 -0
- package/packages/planner/src/index.js +1381 -0
- package/packages/review/README.md +129 -0
- package/packages/review/prompts/reviewer.md +158 -0
- package/packages/review/src/index.js +1403 -0
- package/packages/risk/README.md +178 -0
- package/packages/risk/prompts/risk.md +272 -0
- package/packages/risk/src/index.js +439 -0
- package/packages/session/README.md +165 -0
- package/packages/session/src/index.js +215 -0
- package/packages/test-utils/README.md +96 -0
- package/packages/test-utils/src/index.js +354 -0
- package/packages/tmux/README.md +261 -0
- package/packages/tmux/src/index.js +501 -0
- package/packages/workflow/README.md +317 -0
- package/packages/workflow/prompts/preamble.md +14 -0
- package/packages/workflow/src/index.js +660 -0
- package/packages/workflow/src/proof-of-life.js +74 -0
- package/packages/workspace/README.md +143 -0
- package/packages/workspace/src/index.js +1127 -0
- package/index.js +0 -8
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof-of-life reactor handler factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates a handler that scans open issues and PRs for proof-of-life
|
|
5
|
+
* requests targeting agents in the local agents map, runs health
|
|
6
|
+
* checks, and posts themed responses.
|
|
7
|
+
*
|
|
8
|
+
* Registered once at start and runs on every reactor tick.
|
|
9
|
+
*
|
|
10
|
+
* @module loreli/workflow/proof-of-life
|
|
11
|
+
*/
|
|
12
|
+
import { has, parse, mark } from 'loreli/marker';
|
|
13
|
+
import { logger } from 'loreli/log';
|
|
14
|
+
|
|
15
|
+
const log = logger('proof-of-life');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create the proof-of-life reactor handler.
|
|
19
|
+
*
|
|
20
|
+
* @param {object} orchestrator - Orchestrator with agents map and health().
|
|
21
|
+
* @param {object} hub - GitHub hub for reading/posting comments.
|
|
22
|
+
* @returns {function(string): Promise<void>} Reactor handler receiving repo.
|
|
23
|
+
*/
|
|
24
|
+
export function responder(orchestrator, hub) {
|
|
25
|
+
return async function proofOfLife(repo) {
|
|
26
|
+
const [issues, prs] = await Promise.all([
|
|
27
|
+
hub.issues(repo, { state: 'open', labels: ['loreli'] }).catch(function noop() { return []; }),
|
|
28
|
+
hub.pulls(repo, { state: 'open' }).catch(function noop() { return []; })
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const items = [
|
|
32
|
+
...issues.map(function toItem(i) { return { number: i.number }; }),
|
|
33
|
+
...prs.map(function toItem(p) { return { number: p.number }; })
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
const comments = await hub.comments(repo, item.number);
|
|
38
|
+
|
|
39
|
+
for (const c of comments) {
|
|
40
|
+
if (!has(c.body, 'proof-of-life')) continue;
|
|
41
|
+
|
|
42
|
+
const data = parse(c.body, 'proof-of-life');
|
|
43
|
+
if (!data?.agent) continue;
|
|
44
|
+
|
|
45
|
+
const agent = orchestrator.agents.get(data.agent);
|
|
46
|
+
if (!agent) continue;
|
|
47
|
+
|
|
48
|
+
const responded = comments.some(function alreadyAlive(r) {
|
|
49
|
+
if (!has(r.body, 'alive')) return false;
|
|
50
|
+
const alive = parse(r.body, 'alive');
|
|
51
|
+
return alive?.agent === data.agent && Number(alive.ts) > Number(data.ts);
|
|
52
|
+
});
|
|
53
|
+
if (responded) continue;
|
|
54
|
+
|
|
55
|
+
const verdict = await orchestrator.health(data.agent);
|
|
56
|
+
const aliveMarker = mark('alive', {
|
|
57
|
+
agent: agent.identity.name,
|
|
58
|
+
ts: String(Date.now()),
|
|
59
|
+
status: verdict.status
|
|
60
|
+
});
|
|
61
|
+
const visible = `**${agent.identity.name}** is **${verdict.status}** — ${verdict.details}`;
|
|
62
|
+
const body = `${visible}\n\n${aliveMarker}`;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const scoped = hub.as(agent.identity, agent.role);
|
|
66
|
+
await scoped.comment(repo, item.number, body);
|
|
67
|
+
log.info(`proof-of-life: responded for ${data.agent} on #${item.number} — ${verdict.status}`);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
log.warn(`proof-of-life: failed to respond for ${data.agent} on #${item.number}: ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# loreli/workspace
|
|
2
|
+
|
|
3
|
+
Local workspace lifecycle for Loreli agents.
|
|
4
|
+
|
|
5
|
+
This package prepares agent directories, scaffolds local MCP configs and safety hooks, manages clone-based workspaces, and provides git helpers used by action/review/context flows.
|
|
6
|
+
|
|
7
|
+
## API Reference
|
|
8
|
+
|
|
9
|
+
### Constants
|
|
10
|
+
|
|
11
|
+
| Name | Type | Description |
|
|
12
|
+
|------|------|-------------|
|
|
13
|
+
| `ENTRY` | `{ command: string, args: string[] }` | Loreli MCP entry used in JSON-based configs. |
|
|
14
|
+
| `MCP_JSON` | `string` | Default JSON config body for `.mcp.json` and `.cursor/mcp.json`. |
|
|
15
|
+
| `CODEX_TOML` | `string` | Default TOML config body for `.codex/config.toml`. |
|
|
16
|
+
|
|
17
|
+
### Config Generators
|
|
18
|
+
|
|
19
|
+
#### `codexToml(context?)` → `string`
|
|
20
|
+
|
|
21
|
+
Generate Codex TOML config content with `env_vars = ["GITHUB_TOKEN"]` forwarding and optional agent context env keys.
|
|
22
|
+
|
|
23
|
+
#### `mcpJson(context?, opts?)` → `string`
|
|
24
|
+
|
|
25
|
+
Generate JSON MCP config content with optional agent context, token reference (`tokenRef`), and env file path (`envFile`). Cursor scaffolding keeps both interpolation and envFile fallback for token propagation.
|
|
26
|
+
|
|
27
|
+
### Security/Hook Generators
|
|
28
|
+
|
|
29
|
+
#### `denyScript(denied)` → `string`
|
|
30
|
+
|
|
31
|
+
Generate the shared deny hook script used by Claude/Cursor shell hooks.
|
|
32
|
+
|
|
33
|
+
#### `protectScript()` → `string`
|
|
34
|
+
|
|
35
|
+
Generate the file-write protection hook script for protected paths.
|
|
36
|
+
|
|
37
|
+
#### `claudeHooks()` → `string`
|
|
38
|
+
|
|
39
|
+
Generate `.claude/settings.local.json` hook config content.
|
|
40
|
+
|
|
41
|
+
#### `cursorMatcher(denied)` → `string`
|
|
42
|
+
|
|
43
|
+
Build Cursor `beforeShellExecution` matcher regex from denied commands.
|
|
44
|
+
|
|
45
|
+
#### `cursorHooks(denied)` → `string`
|
|
46
|
+
|
|
47
|
+
Generate `.cursor/hooks.json` hook config content.
|
|
48
|
+
|
|
49
|
+
### Workspace Lifecycle
|
|
50
|
+
|
|
51
|
+
#### `pathFor(name, root?)` → `string`
|
|
52
|
+
|
|
53
|
+
Resolve deterministic workspace path: `<root>/loreli-<name>`.
|
|
54
|
+
|
|
55
|
+
- Default `root`: `~/.loreli/workspaces` (or `LORELI_HOME/workspaces`).
|
|
56
|
+
|
|
57
|
+
#### `prepare(cwd, context?, descriptors?)` → `Promise<void>`
|
|
58
|
+
|
|
59
|
+
Prepare a workspace directory by writing MCP configs, safety files, deny/protect scripts, and merged hook entries.
|
|
60
|
+
|
|
61
|
+
When `context` is provided, session/agent/repo env values are embedded into generated configs. When `descriptors` are provided (from backend scaffolding), descriptor-driven config/hook/file generation is used.
|
|
62
|
+
|
|
63
|
+
This example demonstrates preparing a workspace with context and denied commands. This matters because agents must boot with MCP connectivity and command guardrails. Expected result: config files and hook scripts are created/updated in place.
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import { prepare } from 'loreli/workspace';
|
|
67
|
+
|
|
68
|
+
await prepare('/tmp/loreli-optimus-0', {
|
|
69
|
+
session: 's1',
|
|
70
|
+
agent: 'optimus-0',
|
|
71
|
+
repo: 'owner/repo',
|
|
72
|
+
denied: ['gh', 'curl']
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### `mirror(url, opts?)` → `Promise<string>`
|
|
77
|
+
|
|
78
|
+
Ensure a local bare mirror exists under `<home>/repos`. Fetches if mirror exists, clones if not.
|
|
79
|
+
|
|
80
|
+
#### `create(repo, branch, name, root?, context?, descriptors?)` → `Promise<string>`
|
|
81
|
+
|
|
82
|
+
Create or reuse an agent workspace. Current behavior is clone-based workspace creation (not git worktree-based execution) with branch initialization, optional remote auth setup, and preparation/scaffolding.
|
|
83
|
+
|
|
84
|
+
This example demonstrates provisioning an agent workspace for branch work. This matters because action agents need an isolated git directory with local `.git` state. Expected result: returned `cwd` contains a prepared clone with agent branch checked out.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
import { create } from 'loreli/workspace';
|
|
88
|
+
|
|
89
|
+
const cwd = await create('/path/to/bare-or-local-repo', 'main', 'optimus-0');
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### `clean(name, root?)` → `Promise<void>`
|
|
93
|
+
|
|
94
|
+
Delete an agent workspace directory (best effort). Attempts worktree remove first, then force-removes directory.
|
|
95
|
+
|
|
96
|
+
#### `prune(sessionId, root?)` → `Promise<string[]>`
|
|
97
|
+
|
|
98
|
+
Remove stale `loreli-*` workspaces not owned by `sessionId`.
|
|
99
|
+
|
|
100
|
+
#### `reset(cwd, name, issue?, base?, opts?)` → `Promise<void>`
|
|
101
|
+
|
|
102
|
+
Reset workspace to a clean issue branch from remote `base` (default `main`).
|
|
103
|
+
|
|
104
|
+
When `opts.context` and `opts.descriptors` are provided, `reset()` re-applies
|
|
105
|
+
workspace scaffolding after the branch switch so MCP CLI config files remain
|
|
106
|
+
available for shell-based Loreli tool commands.
|
|
107
|
+
|
|
108
|
+
#### `checkout(cwd, branch, base?, opts?)` → `Promise<void>`
|
|
109
|
+
|
|
110
|
+
Fetch and check out a remote branch in an existing workspace, also syncing local base ref.
|
|
111
|
+
|
|
112
|
+
When `opts.context` and `opts.descriptors` are provided, `checkout()` re-applies
|
|
113
|
+
workspace scaffolding after branch switch for the same reason as `reset()`.
|
|
114
|
+
|
|
115
|
+
#### `hasChanges(cwd)` → `Promise<boolean>`
|
|
116
|
+
|
|
117
|
+
Return whether workspace has uncommitted/untracked changes (`git status --porcelain`).
|
|
118
|
+
|
|
119
|
+
#### `commitAndPush(cwd, message)` → `Promise<{ pushed: boolean, sha: string }>`
|
|
120
|
+
|
|
121
|
+
Stage, commit, and attempt push. Returns commit SHA and whether push succeeded.
|
|
122
|
+
|
|
123
|
+
### Git Context Helpers
|
|
124
|
+
|
|
125
|
+
#### `blame(cwd, file, line)` → `Promise<{ sha: string, author: string, date: string, summary: string }>`
|
|
126
|
+
|
|
127
|
+
Run porcelain git blame for a single line and return parsed metadata.
|
|
128
|
+
|
|
129
|
+
#### `gitlog(cwd, file, opts?)` → `Promise<Array<{ sha: string, date: string, message: string }>>`
|
|
130
|
+
|
|
131
|
+
Run git log for a file and return parsed commit entries.
|
|
132
|
+
|
|
133
|
+
## Scope Boundary
|
|
134
|
+
|
|
135
|
+
In scope:
|
|
136
|
+
- local workspace preparation and cleanup
|
|
137
|
+
- local MCP config/hook generation
|
|
138
|
+
- clone/branch/reset/checkout helper operations
|
|
139
|
+
- git context lookup helpers
|
|
140
|
+
|
|
141
|
+
Out of scope:
|
|
142
|
+
- remote GitHub scaffolding and repository writes (`loreli/hub`)
|
|
143
|
+
- agent process lifecycle (`loreli/agent`, `loreli/orchestrator`)
|