mister-wolf 2.13.0 → 2.14.1

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 (123) hide show
  1. package/README.md +4 -1
  2. package/README.ru.md +4 -1
  3. package/dist/adapters/cli/cli-entry.d.ts.map +1 -1
  4. package/dist/adapters/cli/cli-entry.js +15 -0
  5. package/dist/adapters/cli/cli-entry.js.map +1 -1
  6. package/dist/adapters/cli/commands/analytics.d.ts.map +1 -1
  7. package/dist/adapters/cli/commands/analytics.js +10 -0
  8. package/dist/adapters/cli/commands/analytics.js.map +1 -1
  9. package/dist/adapters/cli/commands/memory-add.js +2 -2
  10. package/dist/adapters/cli/commands/memory-add.js.map +1 -1
  11. package/dist/adapters/cli/commands/memory-aggregate.d.ts +3 -0
  12. package/dist/adapters/cli/commands/memory-aggregate.d.ts.map +1 -0
  13. package/dist/adapters/cli/commands/memory-aggregate.js +31 -0
  14. package/dist/adapters/cli/commands/memory-aggregate.js.map +1 -0
  15. package/dist/adapters/cli/commands/memory-call.d.ts.map +1 -1
  16. package/dist/adapters/cli/commands/memory-call.js +6 -2
  17. package/dist/adapters/cli/commands/memory-call.js.map +1 -1
  18. package/dist/adapters/cli/commands/memory-complain.d.ts +6 -0
  19. package/dist/adapters/cli/commands/memory-complain.d.ts.map +1 -1
  20. package/dist/adapters/cli/commands/memory-complain.js +20 -0
  21. package/dist/adapters/cli/commands/memory-complain.js.map +1 -1
  22. package/dist/adapters/cli/commands/memory-doctor.d.ts.map +1 -1
  23. package/dist/adapters/cli/commands/memory-doctor.js +43 -2
  24. package/dist/adapters/cli/commands/memory-doctor.js.map +1 -1
  25. package/dist/adapters/cli/commands/memory-list.d.ts.map +1 -1
  26. package/dist/adapters/cli/commands/memory-list.js +3 -1
  27. package/dist/adapters/cli/commands/memory-list.js.map +1 -1
  28. package/dist/adapters/cli/commands/memory-recap.d.ts.map +1 -1
  29. package/dist/adapters/cli/commands/memory-recap.js +3 -1
  30. package/dist/adapters/cli/commands/memory-recap.js.map +1 -1
  31. package/dist/adapters/cli/commands/projects.d.ts +3 -0
  32. package/dist/adapters/cli/commands/projects.d.ts.map +1 -0
  33. package/dist/adapters/cli/commands/projects.js +18 -0
  34. package/dist/adapters/cli/commands/projects.js.map +1 -0
  35. package/dist/adapters/cli/type-command-generator.d.ts.map +1 -1
  36. package/dist/adapters/cli/type-command-generator.js +5 -1
  37. package/dist/adapters/cli/type-command-generator.js.map +1 -1
  38. package/dist/adapters/fs/config-file.js +1 -1
  39. package/dist/adapters/fs/config-file.js.map +1 -1
  40. package/dist/adapters/fs/markdown-memory-store.d.ts +3 -1
  41. package/dist/adapters/fs/markdown-memory-store.d.ts.map +1 -1
  42. package/dist/adapters/fs/markdown-memory-store.js +21 -1
  43. package/dist/adapters/fs/markdown-memory-store.js.map +1 -1
  44. package/dist/adapters/fs/projects-registry.d.ts +8 -0
  45. package/dist/adapters/fs/projects-registry.d.ts.map +1 -1
  46. package/dist/adapters/fs/projects-registry.js +43 -0
  47. package/dist/adapters/fs/projects-registry.js.map +1 -1
  48. package/dist/adapters/fs/schema-version.d.ts +2 -0
  49. package/dist/adapters/fs/schema-version.d.ts.map +1 -1
  50. package/dist/adapters/fs/schema-version.js +15 -0
  51. package/dist/adapters/fs/schema-version.js.map +1 -1
  52. package/dist/adapters/mcp/mcp-tools.d.ts.map +1 -1
  53. package/dist/adapters/mcp/mcp-tools.js +2 -1
  54. package/dist/adapters/mcp/mcp-tools.js.map +1 -1
  55. package/dist/adapters/platforms/opencode-adapter.d.ts +8 -1
  56. package/dist/adapters/platforms/opencode-adapter.d.ts.map +1 -1
  57. package/dist/adapters/platforms/opencode-adapter.js +33 -0
  58. package/dist/adapters/platforms/opencode-adapter.js.map +1 -1
  59. package/dist/app/use-cases/add-memory-object.d.ts.map +1 -1
  60. package/dist/app/use-cases/add-memory-object.js +8 -0
  61. package/dist/app/use-cases/add-memory-object.js.map +1 -1
  62. package/dist/app/use-cases/apply-aggregate.d.ts +36 -0
  63. package/dist/app/use-cases/apply-aggregate.d.ts.map +1 -0
  64. package/dist/app/use-cases/apply-aggregate.js +63 -0
  65. package/dist/app/use-cases/apply-aggregate.js.map +1 -0
  66. package/dist/app/use-cases/build-analytics.d.ts +9 -0
  67. package/dist/app/use-cases/build-analytics.d.ts.map +1 -1
  68. package/dist/app/use-cases/build-analytics.js +88 -3
  69. package/dist/app/use-cases/build-analytics.js.map +1 -1
  70. package/dist/app/use-cases/build-projects-list.d.ts +30 -0
  71. package/dist/app/use-cases/build-projects-list.d.ts.map +1 -0
  72. package/dist/app/use-cases/build-projects-list.js +94 -0
  73. package/dist/app/use-cases/build-projects-list.js.map +1 -0
  74. package/dist/app/use-cases/detect-unaggregated-lessons.d.ts +30 -0
  75. package/dist/app/use-cases/detect-unaggregated-lessons.d.ts.map +1 -0
  76. package/dist/app/use-cases/detect-unaggregated-lessons.js +40 -0
  77. package/dist/app/use-cases/detect-unaggregated-lessons.js.map +1 -0
  78. package/dist/app/use-cases/doctor.d.ts +11 -3
  79. package/dist/app/use-cases/doctor.d.ts.map +1 -1
  80. package/dist/app/use-cases/doctor.js +53 -12
  81. package/dist/app/use-cases/doctor.js.map +1 -1
  82. package/dist/app/use-cases/generate-recap.d.ts +10 -0
  83. package/dist/app/use-cases/generate-recap.d.ts.map +1 -1
  84. package/dist/app/use-cases/generate-recap.js +58 -0
  85. package/dist/app/use-cases/generate-recap.js.map +1 -1
  86. package/dist/app/use-cases/get-call-injections.d.ts +6 -0
  87. package/dist/app/use-cases/get-call-injections.d.ts.map +1 -1
  88. package/dist/app/use-cases/get-call-injections.js +14 -1
  89. package/dist/app/use-cases/get-call-injections.js.map +1 -1
  90. package/dist/app/use-cases/init-project.d.ts +3 -1
  91. package/dist/app/use-cases/init-project.d.ts.map +1 -1
  92. package/dist/app/use-cases/init-project.js +36 -16
  93. package/dist/app/use-cases/init-project.js.map +1 -1
  94. package/dist/app/use-cases/record-relation.d.ts.map +1 -1
  95. package/dist/app/use-cases/record-relation.js +4 -0
  96. package/dist/app/use-cases/record-relation.js.map +1 -1
  97. package/dist/bootstrap/container.d.ts.map +1 -1
  98. package/dist/bootstrap/container.js +30 -2
  99. package/dist/bootstrap/container.js.map +1 -1
  100. package/dist/domain/memory-types.d.ts +6 -0
  101. package/dist/domain/memory-types.d.ts.map +1 -1
  102. package/dist/domain/memory-types.js +3 -0
  103. package/dist/domain/memory-types.js.map +1 -1
  104. package/dist/domain/schemas/memory-event-schema.d.ts +2 -0
  105. package/dist/domain/schemas/memory-event-schema.d.ts.map +1 -1
  106. package/dist/domain/schemas/memory-event-schema.js +2 -0
  107. package/dist/domain/schemas/memory-event-schema.js.map +1 -1
  108. package/dist/domain/schemas/relation-schema.d.ts +6 -2
  109. package/dist/domain/schemas/relation-schema.d.ts.map +1 -1
  110. package/dist/domain/schemas/relation-schema.js +8 -0
  111. package/dist/domain/schemas/relation-schema.js.map +1 -1
  112. package/dist/domain/type-schema-builder.d.ts.map +1 -1
  113. package/dist/domain/type-schema-builder.js +3 -1
  114. package/dist/domain/type-schema-builder.js.map +1 -1
  115. package/dist/ports/platform-adapter.port.d.ts +15 -0
  116. package/dist/ports/platform-adapter.port.d.ts.map +1 -1
  117. package/package.json +1 -1
  118. package/templates/.wolf/router.log +1 -0
  119. package/templates/base/agents/executor-lead.md +5 -0
  120. package/templates/base/agents/mr-wolf.md +6 -0
  121. package/templates/base/agents/steward.md +31 -2
  122. package/templates/opencode/plugins/wolf-router.ts +110 -52
  123. package/templates/opencode/plugins/wolf-session-start.js +88 -40
@@ -56,16 +56,15 @@ const WORKER_BODY = `## using-skills: пассивный режим воркер
56
56
  /**
57
57
  * Чистая функция инъекции (юнит-тестируемая): по маркеру в транскрипте и
58
58
  * agent-id решает, какое тело доставить. null = инъекция не нужна.
59
- * Fail-safe (m13): битый вход → null, никогда не бросает.
59
+ * Shape-agnostic (v1 parts / v2 content): части сообщения — `m.parts` ИЛИ
60
+ * `m.content`. Fail-safe (m13): битый вход → null, никогда не бросает.
60
61
  */
61
62
  function computeInjection(messages, agentId) {
62
63
  try {
63
64
  if (!Array.isArray(messages)) return null;
64
65
  // H3: идемпотентность — маркер в ЛЮБОМ сообщении транскрипта → не инъекцируем.
65
- const seen = messages.some(
66
- (m) =>
67
- Array.isArray(m?.parts) &&
68
- m.parts.some((p) => p?.type === 'text' && String(p.text ?? '').includes(MARKER))
66
+ const seen = messages.some((m) =>
67
+ blockList(m).some((p) => p?.type === 'text' && String(p.text ?? '').includes(MARKER))
69
68
  );
70
69
  if (seen) return null;
71
70
  // MAJ-4: worker-* → усечённое тело (без диспетчерского контура using-skills).
@@ -95,9 +94,13 @@ const runWolf = (args) => {
95
94
  .catch(() => null);
96
95
  };
97
96
 
97
+ // Блоки контента сообщения: v1 транскрипт — m.parts, v2 context — m.content.
98
+ const blockList = (message) =>
99
+ Array.isArray(message?.parts) ? message.parts : Array.isArray(message?.content) ? message.content : [];
100
+
98
101
  // Topic = первые слова первого пользовательского сообщения, для `call --for`.
99
102
  const topicOf = (message) =>
100
- (message?.parts ?? [])
103
+ blockList(message)
101
104
  .filter((p) => p.type === 'text' && p.text)
102
105
  .map((p) => p.text)
103
106
  .join(' ')
@@ -106,49 +109,94 @@ const topicOf = (message) =>
106
109
  .slice(0, 10)
107
110
  .join(' ');
108
111
 
112
+ /** MAJ-1: БЕЗ кэша на процесс — каждый запуск без маркера пересчитывает
113
+ * recap/call заново (маркер исчез после /clear или compact → снова).
114
+ * L2 (worker-*) секции recap/call не трогает вообще. */
115
+ async function buildSections(body, firstUser, agentId) {
116
+ const sections = [body];
117
+ if (!(agentId ?? '').startsWith('worker-')) {
118
+ const topic = topicOf(firstUser);
119
+ const [recap, call] = await Promise.all([
120
+ runWolf(['recap']),
121
+ topic ? runWolf(['call', '--for', topic, '--compact', '600']) : null,
122
+ ]);
123
+ if (call?.trim()) sections.unshift(`## Active injections\n${call.trim()}`);
124
+ if (recap?.trim()) sections.unshift(`## Recap\n${recap.trim()}`);
125
+ }
126
+ return sections;
127
+ }
128
+
129
+ const wrap = (sections) =>
130
+ `<session_context>\n${MARKER}\n\n${sections.join('\n\n')}\n</session_context>`;
131
+
109
132
  // MAJ-4: уровень сессии читаем из system-промпта (маркер agent-id в теле
110
133
  // рамки агента). Порядок хуков на первый запрос — на совести рантайма;
111
134
  // пока agent-id не виден, дефолт — полный набор (L0/L1, primary-сессии).
112
135
  let currentAgentId = null;
113
136
 
114
- export const WolfSessionStartPlugin = async () => ({
115
- 'experimental.chat.system.transform': async (_input, output) => {
116
- try {
117
- const m = (output?.system ?? []).join('\n').match(AGENT_ID_RE);
118
- currentAgentId = m ? m[1] : null;
119
- } catch {
120
- /* fail-safe */
121
- }
122
- },
123
- 'experimental.chat.messages.transform': async (_input, output) => {
137
+ // 4.C/P204: один WOLF_SESSION на процесс opencode — и v1-, и v2-фабрика
138
+ // ставят ключ только при отсутствии (спавны наследуют process.env).
139
+ function ensureSession() {
140
+ if (!process.env.WOLF_SESSION) process.env.WOLF_SESSION = 'opc-' + randomUUID();
141
+ }
142
+
143
+ // v1-фабрика: loader v1 вызывает `server()` и получает hook-объект.
144
+ async function server() {
145
+ ensureSession();
146
+ return {
147
+ 'experimental.chat.system.transform': async (_input, output) => {
148
+ try {
149
+ const m = (output?.system ?? []).join('\n').match(AGENT_ID_RE);
150
+ currentAgentId = m ? m[1] : null;
151
+ } catch {
152
+ /* fail-safe */
153
+ }
154
+ },
155
+ 'experimental.chat.messages.transform': async (_input, output) => {
156
+ try {
157
+ const messages = output?.messages;
158
+ const body = computeInjection(messages, currentAgentId);
159
+ if (!body) return;
160
+ const firstUser = messages.find((m) => m.info?.role === 'user');
161
+ if (!firstUser?.parts?.length) return;
162
+
163
+ const sections = await buildSections(body, firstUser, currentAgentId);
164
+ const ref = firstUser.parts[0];
165
+ firstUser.parts.unshift({
166
+ ...ref,
167
+ type: 'text',
168
+ text: wrap(sections),
169
+ });
170
+ } catch {
171
+ // Fail-safe (m13): ошибка плагина не имеет права уронить сессию.
172
+ }
173
+ },
174
+ };
175
+ }
176
+
177
+ // v2-контракт: loader v2 вызывает `setup(ctx)`. agent-id — из текстов
178
+ // event.system (маркер рамки), первый user — по m.role, инъекция — text-блок
179
+ // в начало content (мутация доходит до модельного запроса).
180
+ async function setup(ctx) {
181
+ ensureSession();
182
+ await ctx.session.hook('context', async (event) => {
124
183
  try {
125
- const messages = output?.messages;
184
+ const messages = event?.messages;
185
+ const systemText = (event?.system ?? []).map((s) => s?.text ?? '').join('\n');
186
+ const m = systemText.match(AGENT_ID_RE);
187
+ currentAgentId = m ? m[1] : typeof event?.agent === 'string' ? event.agent : null;
126
188
  const body = computeInjection(messages, currentAgentId);
127
189
  if (!body) return;
128
- const firstUser = messages.find((m) => m.info?.role === 'user');
129
- if (!firstUser?.parts?.length) return;
130
-
131
- const sections = [body];
132
- // MAJ-1: БЕЗ кэша на процесс — каждый запуск без маркера пересчитывает
133
- // recap/call заново (маркер исчез после /clear или compact → снова).
134
- if (!(currentAgentId ?? '').startsWith('worker-')) {
135
- const topic = topicOf(firstUser);
136
- const [recap, call] = await Promise.all([
137
- runWolf(['recap']),
138
- topic ? runWolf(['call', '--for', topic, '--compact', '600']) : null,
139
- ]);
140
- if (call?.trim()) sections.unshift(`## Active injections\n${call.trim()}`);
141
- if (recap?.trim()) sections.unshift(`## Recap\n${recap.trim()}`);
142
- }
190
+ const firstUser = Array.isArray(messages) ? messages.find((mm) => mm?.role === 'user') : null;
191
+ if (!Array.isArray(firstUser?.content) || firstUser.content.length === 0) return;
143
192
 
144
- const ref = firstUser.parts[0];
145
- firstUser.parts.unshift({
146
- ...ref,
147
- type: 'text',
148
- text: `<session_context>\n${MARKER}\n\n${sections.join('\n\n')}\n</session_context>`,
149
- });
193
+ const sections = await buildSections(body, firstUser, currentAgentId);
194
+ firstUser.content.unshift({ type: 'text', text: wrap(sections) });
150
195
  } catch {
151
196
  // Fail-safe (m13): ошибка плагина не имеет права уронить сессию.
152
197
  }
153
- },
154
- });
198
+ });
199
+ }
200
+
201
+ // РОВНО ОДИН export на файл (контракт loader'а opencode): dual v1/v2 entry.
202
+ export default { id: 'wolf-session-start', setup, server };