loreli 0.0.0 → 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 (88) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +670 -97
  3. package/bin/loreli.js +89 -0
  4. package/package.json +74 -14
  5. package/packages/README.md +101 -0
  6. package/packages/action/README.md +98 -0
  7. package/packages/action/src/index.js +656 -0
  8. package/packages/agent/README.md +517 -0
  9. package/packages/agent/src/backends/claude.js +287 -0
  10. package/packages/agent/src/backends/codex.js +278 -0
  11. package/packages/agent/src/backends/cursor.js +294 -0
  12. package/packages/agent/src/backends/index.js +329 -0
  13. package/packages/agent/src/base.js +138 -0
  14. package/packages/agent/src/cli.js +198 -0
  15. package/packages/agent/src/factory.js +119 -0
  16. package/packages/agent/src/index.js +12 -0
  17. package/packages/agent/src/models.js +141 -0
  18. package/packages/agent/src/output.js +62 -0
  19. package/packages/agent/src/session.js +162 -0
  20. package/packages/agent/src/trace.js +186 -0
  21. package/packages/config/README.md +833 -0
  22. package/packages/config/src/defaults.js +134 -0
  23. package/packages/config/src/index.js +192 -0
  24. package/packages/config/src/schema.js +273 -0
  25. package/packages/config/src/validate.js +160 -0
  26. package/packages/context/README.md +165 -0
  27. package/packages/context/src/index.js +198 -0
  28. package/packages/hub/README.md +338 -0
  29. package/packages/hub/src/base.js +154 -0
  30. package/packages/hub/src/github.js +1558 -0
  31. package/packages/hub/src/index.js +79 -0
  32. package/packages/hub/src/labels.js +48 -0
  33. package/packages/identity/README.md +288 -0
  34. package/packages/identity/src/index.js +620 -0
  35. package/packages/identity/src/themes/avatar.js +217 -0
  36. package/packages/identity/src/themes/digimon.js +217 -0
  37. package/packages/identity/src/themes/dragonball.js +217 -0
  38. package/packages/identity/src/themes/lotr.js +217 -0
  39. package/packages/identity/src/themes/marvel.js +217 -0
  40. package/packages/identity/src/themes/pokemon.js +217 -0
  41. package/packages/identity/src/themes/starwars.js +217 -0
  42. package/packages/identity/src/themes/transformers.js +217 -0
  43. package/packages/identity/src/themes/zelda.js +217 -0
  44. package/packages/knowledge/README.md +237 -0
  45. package/packages/knowledge/src/index.js +412 -0
  46. package/packages/log/README.md +93 -0
  47. package/packages/log/src/index.js +252 -0
  48. package/packages/marker/README.md +200 -0
  49. package/packages/marker/src/index.js +184 -0
  50. package/packages/mcp/README.md +279 -0
  51. package/packages/mcp/instructions.md +121 -0
  52. package/packages/mcp/scaffolding/.agents/skills/loreli-context/SKILL.md +89 -0
  53. package/packages/mcp/scaffolding/ISSUE_TEMPLATE/config.yml +2 -0
  54. package/packages/mcp/scaffolding/ISSUE_TEMPLATE/loreli.yml +83 -0
  55. package/packages/mcp/scaffolding/loreli.yml +453 -0
  56. package/packages/mcp/scaffolding/mcp-configs/.codex/config.toml +3 -0
  57. package/packages/mcp/scaffolding/mcp-configs/.cursor/mcp.json +11 -0
  58. package/packages/mcp/scaffolding/mcp-configs/.mcp.json +11 -0
  59. package/packages/mcp/scaffolding/pull-request.md +23 -0
  60. package/packages/mcp/src/index.js +571 -0
  61. package/packages/mcp/src/tools/agents.js +429 -0
  62. package/packages/mcp/src/tools/context.js +199 -0
  63. package/packages/mcp/src/tools/github.js +1199 -0
  64. package/packages/mcp/src/tools/hitl.js +149 -0
  65. package/packages/mcp/src/tools/index.js +17 -0
  66. package/packages/mcp/src/tools/start.js +835 -0
  67. package/packages/mcp/src/tools/status.js +146 -0
  68. package/packages/mcp/src/tools/work.js +124 -0
  69. package/packages/orchestrator/README.md +192 -0
  70. package/packages/orchestrator/src/index.js +1226 -0
  71. package/packages/planner/README.md +168 -0
  72. package/packages/planner/src/index.js +1166 -0
  73. package/packages/review/README.md +129 -0
  74. package/packages/review/src/index.js +1283 -0
  75. package/packages/risk/README.md +119 -0
  76. package/packages/risk/src/index.js +428 -0
  77. package/packages/session/README.md +165 -0
  78. package/packages/session/src/index.js +215 -0
  79. package/packages/test-utils/README.md +96 -0
  80. package/packages/test-utils/src/index.js +354 -0
  81. package/packages/tmux/README.md +261 -0
  82. package/packages/tmux/src/index.js +452 -0
  83. package/packages/workflow/README.md +313 -0
  84. package/packages/workflow/src/index.js +481 -0
  85. package/packages/workflow/src/proof-of-life.js +74 -0
  86. package/packages/workspace/README.md +143 -0
  87. package/packages/workspace/src/index.js +1076 -0
  88. package/index.js +0 -8
@@ -0,0 +1,149 @@
1
+ import { logger } from 'loreli/log';
2
+ import { check } from 'loreli/config';
3
+ import { has, parse } from 'loreli/marker';
4
+
5
+ const log = logger('hitl');
6
+
7
+ /**
8
+ * Human In The Loop (HITL) tools.
9
+ *
10
+ * `hitl` hands off a PR to human reviewers after agent approval.
11
+ * `watch` checks for new human feedback using timestamp filtering.
12
+ */
13
+ export default {
14
+ hitl: {
15
+ title: 'HITL',
16
+ description: 'Hand off a PR to human reviewers. Requests review, assigns users, posts a summary comment tagging reviewers. Only meaningful when merge.hitl is true.',
17
+ schema: {
18
+ type: 'object',
19
+ properties: {
20
+ repo: { type: 'string', description: 'Target repository (owner/name).' },
21
+ pr: { type: 'number', description: 'Pull request number.' }
22
+ },
23
+ required: ['repo', 'pr']
24
+ },
25
+ /**
26
+ * @param {object} args - Tool arguments.
27
+ * @param {object} ctx - Execution context.
28
+ * @returns {Promise<object>} HITL result with reviewer list.
29
+ */
30
+ async exec(args, ctx) {
31
+ check.repo(args.repo);
32
+ check.positive(args.pr, 'PR number');
33
+ const { repo, pr } = args;
34
+ const reviewers = ctx.config?.get?.('reviewers') ?? [];
35
+
36
+ if (!reviewers.length) {
37
+ return {
38
+ content: [{
39
+ type: 'text',
40
+ text: `No reviewers configured — merge.hitl is false. PR #${pr} can be merged directly.`
41
+ }]
42
+ };
43
+ }
44
+
45
+ log.info(`hitl PR #${pr} for human review: ${reviewers.join(', ')}`);
46
+
47
+ // Delegate to review workflow which handles request, assign, comment, and agent cleanup
48
+ const result = await ctx.review.hitl(repo, pr);
49
+
50
+ // Persist HITL state for watch polling
51
+ if (ctx.sessionId && ctx.storage) {
52
+ try {
53
+ const agents = ctx.storage.agents ? await ctx.storage.agents(ctx.sessionId) : [];
54
+ for (const name of agents) {
55
+ const data = await ctx.storage.load(ctx.sessionId, name);
56
+ if (data) {
57
+ data.state = 'awaiting_hitl';
58
+ data.reviewers = result.reviewers;
59
+ data.hitlAt = result.hitlAt;
60
+ await ctx.storage.save(ctx.sessionId, name, data);
61
+ }
62
+ }
63
+ } catch { /* best-effort persistence */ }
64
+ }
65
+
66
+ return {
67
+ content: [{
68
+ type: 'text',
69
+ text: [
70
+ `PR #${pr} handed to Human In The Loop`,
71
+ `Reviewers: ${result.reviewers.join(', ')}`,
72
+ `HITL at: ${result.hitlAt}`,
73
+ 'All active agents have been shut down.'
74
+ ].join('\n')
75
+ }]
76
+ };
77
+ }
78
+ },
79
+
80
+ watch: {
81
+ title: 'Watch',
82
+ description: 'Check an HITL PR for new human feedback. Returns comments posted after the HITL timestamp, filtering out known agent comments.',
83
+ schema: {
84
+ type: 'object',
85
+ properties: {
86
+ repo: { type: 'string', description: 'Target repository (owner/name).' },
87
+ pr: { type: 'number', description: 'Pull request number.' },
88
+ since: { type: 'string', description: 'ISO timestamp to filter comments after (hitlAt).' }
89
+ },
90
+ required: ['repo', 'pr', 'since']
91
+ },
92
+ /**
93
+ * @param {object} args - Tool arguments.
94
+ * @param {object} ctx - Execution context.
95
+ * @returns {Promise<object>} Watch result with status and optional feedback.
96
+ */
97
+ async exec(args, ctx) {
98
+ check.repo(args.repo);
99
+ check.positive(args.pr, 'PR number');
100
+ const { repo, pr, since } = args;
101
+
102
+ // Inline: pending() was a 3-line hub method — timestamp filter on comments()
103
+ const allComments = await ctx.hub.comments(repo, pr);
104
+ const comments = allComments.filter(function afterHitl(c) { return c.created > since; });
105
+
106
+ // Filter out comments whose agent marker names an identity in the
107
+ // registry's active list. Both agent and human comments may carry
108
+ // the agent marker when posted via hub.as(identity, role).comment();
109
+ // we distinguish by whether the marker's name is a known agent.
110
+ const activeNames = new Set(
111
+ (ctx.identityRegistry?.active?.() ?? []).map(function name(i) { return i.name; })
112
+ );
113
+ const human = comments.filter(function notAgent(c) {
114
+ if (!has(c.body, 'agent')) return true;
115
+ const data = parse(c.body, 'agent');
116
+ return !data?.name || !activeNames.has(data.name);
117
+ });
118
+
119
+ if (!human.length) {
120
+ return {
121
+ content: [{
122
+ type: 'text',
123
+ text: JSON.stringify({ status: 'waiting', pr, checked: new Date().toISOString() })
124
+ }]
125
+ };
126
+ }
127
+
128
+ // Human feedback found — trigger rework via action workflow
129
+ if (ctx.action) {
130
+ try {
131
+ await ctx.action.rework(repo, pr, human);
132
+ } catch { /* rework is best-effort; we still return the feedback */ }
133
+ }
134
+
135
+ return {
136
+ content: [{
137
+ type: 'text',
138
+ text: JSON.stringify({
139
+ status: 'feedback',
140
+ pr,
141
+ comments: human.map(function format(c) {
142
+ return { author: c.author, body: c.body, created: c.created };
143
+ })
144
+ })
145
+ }]
146
+ };
147
+ }
148
+ }
149
+ };
@@ -0,0 +1,17 @@
1
+ import start from './start.js';
2
+ import agents from './agents.js';
3
+ import work from './work.js';
4
+ import status from './status.js';
5
+ import hitl from './hitl.js';
6
+ import github from './github.js';
7
+ import context from './context.js';
8
+
9
+ /**
10
+ * All tool definitions aggregated from individual modules.
11
+ *
12
+ * @returns {Record<string, object>} Map of tool name to tool definition.
13
+ */
14
+ export function allTools() {
15
+ return { ...start, ...agents, ...work, ...status, ...hitl, ...github, ...context };
16
+ }
17
+