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.
Files changed (104) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +710 -97
  3. package/bin/loreli.js +89 -0
  4. package/package.json +77 -14
  5. package/packages/README.md +101 -0
  6. package/packages/action/README.md +98 -0
  7. package/packages/action/prompts/action.md +172 -0
  8. package/packages/action/src/index.js +684 -0
  9. package/packages/agent/README.md +606 -0
  10. package/packages/agent/src/backends/claude.js +387 -0
  11. package/packages/agent/src/backends/codex.js +351 -0
  12. package/packages/agent/src/backends/cursor.js +371 -0
  13. package/packages/agent/src/backends/index.js +486 -0
  14. package/packages/agent/src/base.js +138 -0
  15. package/packages/agent/src/cli.js +275 -0
  16. package/packages/agent/src/discover.js +396 -0
  17. package/packages/agent/src/factory.js +124 -0
  18. package/packages/agent/src/index.js +12 -0
  19. package/packages/agent/src/models.js +159 -0
  20. package/packages/agent/src/output.js +62 -0
  21. package/packages/agent/src/session.js +162 -0
  22. package/packages/agent/src/trace.js +186 -0
  23. package/packages/classify/README.md +136 -0
  24. package/packages/classify/prompts/blocker.md +12 -0
  25. package/packages/classify/prompts/feedback.md +14 -0
  26. package/packages/classify/prompts/pane-state.md +20 -0
  27. package/packages/classify/src/index.js +81 -0
  28. package/packages/config/README.md +898 -0
  29. package/packages/config/src/defaults.js +145 -0
  30. package/packages/config/src/index.js +223 -0
  31. package/packages/config/src/schema.js +291 -0
  32. package/packages/config/src/validate.js +160 -0
  33. package/packages/context/README.md +165 -0
  34. package/packages/context/src/index.js +198 -0
  35. package/packages/hub/README.md +338 -0
  36. package/packages/hub/src/base.js +154 -0
  37. package/packages/hub/src/github.js +1597 -0
  38. package/packages/hub/src/index.js +79 -0
  39. package/packages/hub/src/labels.js +48 -0
  40. package/packages/identity/README.md +288 -0
  41. package/packages/identity/src/index.js +620 -0
  42. package/packages/identity/src/themes/avatar.js +217 -0
  43. package/packages/identity/src/themes/digimon.js +217 -0
  44. package/packages/identity/src/themes/dragonball.js +217 -0
  45. package/packages/identity/src/themes/lotr.js +217 -0
  46. package/packages/identity/src/themes/marvel.js +217 -0
  47. package/packages/identity/src/themes/pokemon.js +217 -0
  48. package/packages/identity/src/themes/starwars.js +217 -0
  49. package/packages/identity/src/themes/transformers.js +217 -0
  50. package/packages/identity/src/themes/zelda.js +217 -0
  51. package/packages/knowledge/README.md +217 -0
  52. package/packages/knowledge/src/index.js +243 -0
  53. package/packages/log/README.md +93 -0
  54. package/packages/log/src/index.js +252 -0
  55. package/packages/marker/README.md +200 -0
  56. package/packages/marker/src/index.js +184 -0
  57. package/packages/mcp/README.md +323 -0
  58. package/packages/mcp/instructions.md +126 -0
  59. package/packages/mcp/scaffolding/.agents/skills/loreli-context/SKILL.md +89 -0
  60. package/packages/mcp/scaffolding/ISSUE_TEMPLATE/config.yml +2 -0
  61. package/packages/mcp/scaffolding/ISSUE_TEMPLATE/loreli.yml +83 -0
  62. package/packages/mcp/scaffolding/loreli.yml +491 -0
  63. package/packages/mcp/scaffolding/mcp-configs/.codex/config.toml +4 -0
  64. package/packages/mcp/scaffolding/mcp-configs/.cursor/mcp.json +14 -0
  65. package/packages/mcp/scaffolding/mcp-configs/.mcp.json +14 -0
  66. package/packages/mcp/scaffolding/pull-request.md +23 -0
  67. package/packages/mcp/src/index.js +600 -0
  68. package/packages/mcp/src/tools/agent-context.js +44 -0
  69. package/packages/mcp/src/tools/agents.js +450 -0
  70. package/packages/mcp/src/tools/context.js +200 -0
  71. package/packages/mcp/src/tools/github.js +1163 -0
  72. package/packages/mcp/src/tools/hitl.js +162 -0
  73. package/packages/mcp/src/tools/index.js +18 -0
  74. package/packages/mcp/src/tools/refactor.js +227 -0
  75. package/packages/mcp/src/tools/repo.js +44 -0
  76. package/packages/mcp/src/tools/start.js +904 -0
  77. package/packages/mcp/src/tools/status.js +149 -0
  78. package/packages/mcp/src/tools/work.js +134 -0
  79. package/packages/orchestrator/README.md +192 -0
  80. package/packages/orchestrator/src/index.js +1492 -0
  81. package/packages/planner/README.md +251 -0
  82. package/packages/planner/prompts/plan-reviewer.md +109 -0
  83. package/packages/planner/prompts/planner.md +191 -0
  84. package/packages/planner/prompts/tiebreaker-reviewer.md +71 -0
  85. package/packages/planner/src/index.js +1381 -0
  86. package/packages/review/README.md +129 -0
  87. package/packages/review/prompts/reviewer.md +158 -0
  88. package/packages/review/src/index.js +1403 -0
  89. package/packages/risk/README.md +178 -0
  90. package/packages/risk/prompts/risk.md +272 -0
  91. package/packages/risk/src/index.js +439 -0
  92. package/packages/session/README.md +165 -0
  93. package/packages/session/src/index.js +215 -0
  94. package/packages/test-utils/README.md +96 -0
  95. package/packages/test-utils/src/index.js +354 -0
  96. package/packages/tmux/README.md +261 -0
  97. package/packages/tmux/src/index.js +501 -0
  98. package/packages/workflow/README.md +317 -0
  99. package/packages/workflow/prompts/preamble.md +14 -0
  100. package/packages/workflow/src/index.js +660 -0
  101. package/packages/workflow/src/proof-of-life.js +74 -0
  102. package/packages/workspace/README.md +143 -0
  103. package/packages/workspace/src/index.js +1127 -0
  104. 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`)