engineering-memory 1.11.20 → 1.11.21

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 (30) hide show
  1. package/bin/engineering-memory.mjs +14 -24
  2. package/install/localization.generated.mjs +18 -0
  3. package/package.json +1 -1
  4. package/runtime/build.json +1 -1
  5. package/runtime/dist/src/auth/browser-auth.js +15 -4
  6. package/runtime/dist/src/config.js +1 -0
  7. package/runtime/dist/src/git/git-inspector.js +10 -0
  8. package/runtime/dist/src/localization/catalogue.generated.js +786 -0
  9. package/runtime/dist/src/mcp/delivery-tools.js +15 -48
  10. package/runtime/dist/src/mcp/onboarding-tools.js +289 -618
  11. package/runtime/dist/src/mcp/questionnaire-tools.js +23 -26
  12. package/runtime/dist/src/mcp/status-meaning-tools.js +12 -86
  13. package/runtime/dist/src/mcp/status-remap-tools.js +252 -0
  14. package/runtime/dist/src/mcp/tool-annotations.js +1 -0
  15. package/runtime/dist/src/mcp/tool-definitions.js +33 -55
  16. package/runtime/dist/src/mcp/workflow-tools.js +17 -108
  17. package/runtime/dist/src/mcp/worktree-tools.js +168 -250
  18. package/runtime/dist/src/runtime/bridge-service.js +100 -94
  19. package/runtime/dist/src/runtime/create-bridge-service.js +4 -2
  20. package/runtime/dist/src/runtime/language-store.js +6 -0
  21. package/runtime/dist/src/runtime/release-notes.js +6 -6
  22. package/runtime/dist/src/runtime/release-report.js +30 -30
  23. package/runtime/dist/src/runtime/task-start.js +75 -73
  24. package/runtime/dist/src/runtime/texts.js +135 -0
  25. package/runtime/dist/src/runtime/worktree-pool.js +30 -5
  26. package/runtime/dist/src/runtime/worktree-preparation.js +3 -2
  27. package/runtime/dist/src/utilities/process.js +7 -0
  28. package/skill/references/lifecycle.md +21 -3
  29. package/skill/references/project-onboarding.md +5 -2
  30. package/skill/references/questionnaires.md +3 -1
@@ -1,5 +1,6 @@
1
1
  import * as z from 'zod/v4';
2
2
  import { languageTag } from '../runtime/questionnaire-store.js';
3
+ import { texts } from '../runtime/texts.js';
3
4
  import { sha256, stableStringify } from '../utilities/hash.js';
4
5
  import { answerChoice, askQuestionnaire } from './questionnaire-tools.js';
5
6
  import { assertSafeToPersist } from '../runtime/offline-outbox.js';
@@ -11,7 +12,10 @@ const role = z.enum([
11
12
  'blocked_declared',
12
13
  ]);
13
14
  const mode = z.enum(['automatic', 'confirm', 'ignore']);
14
- const navigation = z.tuple([z.string().trim().min(1).max(120), z.string().trim().min(1).max(400)]);
15
+ const navigation = z.strictObject({
16
+ label: z.string().trim().min(1).max(120),
17
+ description: z.string().trim().min(1).max(400),
18
+ });
15
19
  const wording = z
16
20
  .object({
17
21
  roles: z.record(role, z
@@ -75,104 +79,6 @@ const workflowPage = z.object({
75
79
  offset: z.number().int().min(0),
76
80
  limit: z.number().int().min(1).max(100),
77
81
  });
78
- const copy = {
79
- tr: {
80
- roles: {
81
- work_started: {
82
- title: 'Geliştirme',
83
- message: 'Geliştirmeye başlayınca hangi kolon kullanılsın?',
84
- context: 'Yeni işin açıldığı kolondan ayrı olarak, geliştirmeye başlama adımını ayarlıyoruz.',
85
- example: 'Ödeme hatasını düzeltmeye başladığında kullanılacak kolonu seçiyorsun.',
86
- },
87
- pr_opened: {
88
- title: 'İncelemeye hazır PR',
89
- message: 'PR incelemeye hazır olunca hangi kolon kullanılsın?',
90
- context: 'Taslak PR davranışı aynı kalır; burada incelemeye hazır PR adımını ayarlıyoruz.',
91
- example: 'Değişikliğini bitirip ekip arkadaşının incelemesine açtığında kullanılacak kolon.',
92
- },
93
- all_prs_merged: {
94
- title: 'Bütün PR’lar birleşti',
95
- message: 'İşin bütün PR’ları birleşince hangi kolon kullanılsın?',
96
- context: 'Bu işe bağlı bütün PR’ların birleştiği adımı ayarlıyoruz.',
97
- example: 'Hem web hem sunucu değişiklikleri birleştirildiğinde kullanılacak kolon.',
98
- },
99
- test_failed: {
100
- title: 'Başarısız test',
101
- message: 'Test başarısız olunca hangi kolon kullanılsın?',
102
- context: 'Başarısız testin ardından yapılacak düzeltmeler için kolon seçiyoruz.',
103
- example: 'Ödeme testinde hata bulundu; düzeltme bekleyen iş için kullanılacak kolon.',
104
- },
105
- blocked_declared: {
106
- title: 'Park edilen işler',
107
- message: 'Beklemeye alınan işler hangi kolonda park edilsin?',
108
- context: 'Projenin aktif park kolonunu seçiyoruz; mevcut işler yerinde kalacak.',
109
- example: 'Dış servisten yanıt beklediğin için işi beklemeye aldığında kullanılacak kolon.',
110
- },
111
- },
112
- modes: { automatic: 'Otomatik', confirm: 'Onay sor', ignore: 'Olayı dikkate alma' },
113
- page: 'Sayfa',
114
- next: ['Sonraki kolonlar', 'Aynı kararın sonraki kolonlarını göster.'],
115
- previous: ['Önceki kolonlar', 'Aynı kararın önceki kolonlarına dön.'],
116
- defer: ['Şimdi kaydetme', 'Seçimleri uygulama; bu deneme ertelenmiş olarak kalır.'],
117
- approve: [
118
- 'Bu ayarları kaydet',
119
- 'Gösterilen beş tercihi birlikte kaydet; mevcut işleri taşıma.',
120
- ],
121
- review: {
122
- message: 'Bu akış ayarlarını birlikte kaydedelim mi?',
123
- context: 'Beş kolon ve davranış aşağıda. Taslak PR ve yeni işin başlangıç kolonu değişmez. Bu işlem yalnızca ayarları kaydeder; olay çalıştırmaz.',
124
- example: 'Beklemeye alınan işler için Beklemede kolonunu seçtiysen proje bundan sonra bu tercihi saklar; önceki işler yerinde kalır.',
125
- },
126
- },
127
- en: {
128
- roles: {
129
- work_started: {
130
- title: 'Development',
131
- message: 'Which stage should represent starting development?',
132
- context: 'This is separate from the stage where new work is created.',
133
- example: 'Choose the stage used when you begin fixing a payment bug.',
134
- },
135
- pr_opened: {
136
- title: 'PR ready for review',
137
- message: 'Which stage should represent a PR ready for review?',
138
- context: 'Draft PR behavior stays unchanged; this configures the ready-for-review step.',
139
- example: 'Use this stage when your completed change is ready for a teammate to review.',
140
- },
141
- all_prs_merged: {
142
- title: 'All PRs merged',
143
- message: 'Which stage should represent all PRs being merged?',
144
- context: 'This configures the step after every PR belonging to the work has merged.',
145
- example: 'Both the web change and its backend change have been merged.',
146
- },
147
- test_failed: {
148
- title: 'Failed test',
149
- message: 'Which stage should represent a failed test?',
150
- context: 'Choose the stage for work that needs changes after a failed test.',
151
- example: 'A payment test found a problem and the work needs a correction.',
152
- },
153
- blocked_declared: {
154
- title: 'Parked work',
155
- message: 'Which stage should hold parked work?',
156
- context: 'Choose the active parked stage; existing work stays where it is.',
157
- example: 'You put a task on hold while waiting for an external service.',
158
- },
159
- },
160
- modes: { automatic: 'Automatic', confirm: 'Ask for approval', ignore: 'Ignore this event' },
161
- page: 'Page',
162
- next: ['Next stages', 'Show the next stages for this same decision.'],
163
- previous: ['Previous stages', 'Return to the previous stages for this same decision.'],
164
- defer: ['Do not save now', 'Apply nothing; this attempt remains deferred.'],
165
- approve: [
166
- 'Save these settings',
167
- 'Save the five displayed choices together without moving existing work.',
168
- ],
169
- review: {
170
- message: 'Save these workflow settings together?',
171
- context: 'The five stages and behaviors appear below. Draft PR and new-work initial settings stay unchanged. This saves configuration only; no event is executed.',
172
- example: 'Choosing On Hold for parked work stores that preference for the project; earlier tasks remain in place.',
173
- },
174
- },
175
- };
176
82
  function stageQuestion(input, text, language, stages, recommendation, setupId, selected, page, visit) {
177
83
  const recommended = stages.find((item) => item.id === recommendation.statusId);
178
84
  const others = stages.filter((item) => item.id !== recommendation.statusId);
@@ -192,10 +98,14 @@ function stageQuestion(input, text, language, stages, recommendation, setupId, s
192
98
  .slice(0, 400),
193
99
  }));
194
100
  if (page > 0)
195
- options.push({ id: 'previous', label: text.previous[0], description: text.previous[1] });
101
+ options.push({
102
+ id: 'previous',
103
+ label: text.previous.label,
104
+ description: text.previous.description,
105
+ });
196
106
  if (page + 1 < count)
197
- options.push({ id: 'next', label: text.next[0], description: text.next[1] });
198
- options.push({ id: 'defer', label: text.defer[0], description: text.defer[1] });
107
+ options.push({ id: 'next', label: text.next.label, description: text.next.description });
108
+ options.push({ id: 'defer', label: text.defer.label, description: text.defer.description });
199
109
  return {
200
110
  questionnaireId: 'workflow-role-' +
201
111
  sha256(stableStringify({ setupId, selected, event: recommendation.event, page, visit })),
@@ -218,7 +128,7 @@ function stageQuestion(input, text, language, stages, recommendation, setupId, s
218
128
  }
219
129
  export function registerWorkflowTools(server, service) {
220
130
  server.registerTool('work_item.setup_workflow', {
221
- description: 'Review five project workflow roles in durable native forms and save them together. First read work_item.workflow and supply its exact snapshot plus five deliberate recommendations, explicit modes and reasons in the user language. The current task must be resumed in this repository. All active stages are reachable through pages; existing work and draft PR settings stay unchanged. Questions are critical and follow the task mode; feedback is not consent. Retry identical input to resume. After deferral or a mode-invalidated agent answer, use a new decisionAttempt only when reconsideration is authorized. Use copy for languages other than Turkish/English; translate every field. Never silently replace a stale snapshot. This does not fire events.',
131
+ description: 'Review five project workflow roles in durable native forms and save them together. First read work_item.workflow and supply its exact snapshot plus five deliberate recommendations, explicit modes and reasons in the user language. The current task must be resumed in this repository. All active stages are reachable through pages; existing work and draft PR settings stay unchanged. Questions are critical and follow the task mode; feedback is not consent. Retry identical input to resume. After deferral or a mode-invalidated agent answer, use a new decisionAttempt only when reconsideration is authorized. Supply copy, translating every field, when the product text catalogue lacks the conversation language. Never silently replace a stale snapshot. This does not fire events.',
222
132
  inputSchema: setupInput,
223
133
  }, async (input, context) => setupWorkflow(server, service, input, context));
224
134
  }
@@ -233,11 +143,10 @@ async function setupWorkflow(server, service, input, context) {
233
143
  catch {
234
144
  return refusal('Remove sensitive content from the workflow question and its retry arguments before continuing.', 'work_item.setup_workflow');
235
145
  }
236
- const language = input.language ?? (await service.language());
146
+ const language = await service.language(input.language);
237
147
  if (!language)
238
148
  return refusal('Read session.entry with the conversation language first.', 'session.entry');
239
- const baseLanguage = language.split('-')[0];
240
- const text = input.copy ?? (baseLanguage === 'tr' || baseLanguage === 'en' ? copy[baseLanguage] : undefined);
149
+ const text = input.copy ?? wording.safeParse(texts('workflow', language)).data;
241
150
  if (!text)
242
151
  return refusal('Supply every copy field in the conversation language, preserving this snapshot and requestKey.', 'work_item.setup_workflow');
243
152
  const stages = [];
@@ -343,8 +252,8 @@ async function setupWorkflow(server, service, input, context) {
343
252
  .join('\n'),
344
253
  example: text.review.example,
345
254
  options: [
346
- { id: 'approve', label: text.approve[0], description: text.approve[1] },
347
- { id: 'defer', label: text.defer[0], description: text.defer[1] },
255
+ { id: 'approve', label: text.approve.label, description: text.approve.description },
256
+ { id: 'defer', label: text.defer.label, description: text.defer.description },
348
257
  ],
349
258
  binding: {
350
259
  setupId,