@mmerterden/multi-agent-pipeline 20.37.0 → 20.37.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 (37) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/docs/facts.json +2 -2
  3. package/docs/features.md +1 -1
  4. package/docs/recovery-guide.md +1 -1
  5. package/install/catalog-history.json +1 -1
  6. package/manifest.json +40 -35
  7. package/package.json +1 -1
  8. package/pipeline/commands/multi-agent/manual-test/SKILL.md +12 -7
  9. package/pipeline/multi-agent-refs/audit-guide.md +20 -0
  10. package/pipeline/multi-agent-refs/features/commit-multi-repo.md +63 -0
  11. package/pipeline/multi-agent-refs/features/dev-multi-repo.md +51 -0
  12. package/pipeline/multi-agent-refs/features/test-gap.md +40 -0
  13. package/pipeline/multi-agent-refs/features/worktree-finalize.md +1 -1
  14. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +12 -9
  15. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +4 -4
  16. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +8 -47
  17. package/pipeline/multi-agent-refs/phases/phase-3-review.md +21 -65
  18. package/pipeline/multi-agent-refs/phases/phase-4-commit.md +9 -59
  19. package/pipeline/multi-agent-refs/phases/phase-5-report.md +0 -31
  20. package/pipeline/multi-agent-refs/rules.md +1 -1
  21. package/pipeline/office/index.html +6 -3
  22. package/pipeline/office/toolkit.json +1 -1
  23. package/pipeline/rules/figma-pipeline.md +6 -3
  24. package/pipeline/schemas/prefs.schema.json +1 -1
  25. package/pipeline/scripts/_memory-policy.mjs +27 -5
  26. package/pipeline/scripts/checkpoint-fold.sh +59 -0
  27. package/pipeline/scripts/gate-ledger.mjs +1 -1
  28. package/pipeline/scripts/office-control.mjs +41 -15
  29. package/pipeline/scripts/offload-ref.sh +1 -1
  30. package/pipeline/scripts/rework-rulings.mjs +5 -3
  31. package/pipeline/scripts/scope-check-gate.mjs +15 -2
  32. package/pipeline/scripts/user-test-handoff.sh +203 -0
  33. package/pipeline/scripts/validate-planning.mjs +5 -3
  34. package/pipeline/scripts/validate-triage.mjs +2 -1
  35. package/pipeline/scripts/write-state.mjs +13 -4
  36. package/pipeline/skills/.skill-manifest.json +2 -2
  37. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +12 -7
@@ -1404,7 +1404,7 @@ pre.log {
1404
1404
  <div class="toast" id="toast" role="status"></div>
1405
1405
  <script nonce="{{NONCE}}">
1406
1406
  "use strict";
1407
- const BUILD = "c98eeb780915";
1407
+ const BUILD = "eb68cf3bafe4";
1408
1408
  (() => {
1409
1409
  const ATLAS = ["ARCHIVE_BOXES","BIN","BOOKSHELF","CACTUS","CLOCK","COFFEE","COFFEE_MACHINE","COFFEE_TABLE","COUNTER_SINK","CUSHIONED_BENCH","CUSHIONED_CHAIR_BACK","CUSHIONED_CHAIR_FRONT","CUSHIONED_CHAIR_SIDE","DESK_FRONT","DESK_SIDE","DEVICE_STAND","DOUBLE_BOOKSHELF","FILING_CABINET","FRIDGE","HANGING_PLANT","LARGE_PAINTING","LARGE_PLANT","MAILBOX","MOP_BUCKET","PC_BACK","PC_FRONT_OFF","PC_FRONT_ON_1","PC_FRONT_ON_2","PC_FRONT_ON_3","PC_SIDE","PLANT","PLANT_2","POT","PRINTER","RECEPTION_DESK","SERVER_RACK","SERVER_RACK_2","SMALL_PAINTING","SMALL_PAINTING_2","SMALL_TABLE_FRONT","SMALL_TABLE_SIDE","SOFA_BACK","SOFA_FRONT","SOFA_SIDE","TABLE_FRONT","TOILET_STALL","VENDING","WASHBASIN","WATER_COOLER","WHITEBOARD","WOODEN_BENCH","WOODEN_CHAIR_BACK","WOODEN_CHAIR_FRONT","WOODEN_CHAIR_SIDE","char_0","char_1","char_12","char_13","char_14","char_15","char_16","char_17","char_18","char_19","char_2","char_20","char_21","char_22","char_23","char_24","char_25","char_26","char_27","char_28","char_29","char_3","char_30","char_4","char_5","floor_0","floor_1","floor_2","floor_3","floor_4","floor_5","floor_6","floor_7","floor_8","wall_0"];
1410
1410
  const STRINGS = {"en":{"app.title":"Office","archive.empty":"No runs recorded yet.","archive.log":"Log","archive.postmortem":"Ask for a post-mortem","ask.copy":"Copy command","ask.handOff":"Give a job to someone","ask.label":"Ask an agent","ask.note":"Starting an ask from the panel is not available yet, because launch input refuses links in free text. Copy the command and run it in a terminal.","ask.placeholder":"Ask an agent about this screen","autopilot.ceiling":"ceiling {v}","autopilot.switch":"Autopilot on or off","autopilot.onHint":"Watches the repositories below and takes up to {n} items at a time.","autopilot.offHint":"Pick the repositories to watch, then turn it on.","autopilot.noRepoHint":"Add a repository in the terminal first; then it can be turned on here.","autopilot.ofSlots":"of {n} at a time","autopilot.reposTitle":"Watched repositories","autopilot.pickOn":"Pick a new selection to change which repositories it watches.","autopilot.saveOnly":"Save the selection without starting","autopilot.saveTitle":"Save the autopilot selection","autopilot.stopNowBtn":"Stop now","autopilot.stopNowTitle":"Stop the autopilot now","autopilot.addInTerminal":"A new repository is added in the terminal, because it asks for its sources and label:","autopilot.configureOnly":"Save the selection only, schedule nothing","autopilot.credsBad":"Credentials: problems, nothing will be scheduled","autopilot.credsOk":"Credentials: readable","autopilot.drop":"Drop: {v}","autopilot.keep":"Keep: {v}","autopilot.noRepo":"No configured repository.","autopilot.off":"Autopilot off","autopilot.offDrain":"Work in flight finishes; nothing new is taken.","autopilot.offNow":"In-flight items are stopped and their runs marked abandoned.","autopilot.offTitle":"Turn the autopilot off","autopilot.on":"Autopilot on","autopilot.onTitle":"Turn the autopilot on","autopilot.pick":"Pick the repositories to watch.","autopilot.pickOne":"Select at least one repository.","autopilot.queued":"Queued","autopilot.running":"Running","autopilot.slots":"Slots","autopilot.state":"State","autopilot.stopNow":"Also stop what is in flight now","autopilot.today":"Today","autopilot.turnOff":"Turn off","autopilot.turnOn":"Turn on","autopilot.unknown":"Autopilot ?","back":"Back","bot.autopilot":"Autopilot","bot.doing":"Watching the queue","cancel":"Cancel","chat.answer":"Answer","chat.answerTitle":"Answer {id}","chat.answered":"Answered","chat.kill":"Kill","chat.killBody":"This stops the session and removes the worktree. The remote branch and logs are kept.","chat.killTitle":"Kill {id}","chat.noResult":"No result yet.","chat.noTranscript":"No transcript for this seat.","chat.nowIn":"now in phase {n}","chat.older":"Load older","chat.pickFirst":"Pick an option first.","chat.queued":"Queued","chat.queuedReplaced":"Queued (replaced the previous one)","chat.replaces":"Replaces the unread instruction:","chat.resume":"Resume","chat.resumeBody":"Returns the plan that resumes this run in the background.","chat.resumePlan":"Resume plan","chat.resumeTitle":"Resume {id}","chat.runGone":"This run is no longer on the floor; nothing can be sent to it from here.","chat.send":"Send: {v}","chat.sendBtn":"Send","chat.steer":"Steer","chat.steerLabel":"Steer instruction","chat.steerPlaceholder":"Instruction for the next phase (steer)","chat.steerTitle":"Steer {id}","chat.steerWhen":"Applied at the entry to the next phase","chat.toolResult":"Tool result","cleanup.done":"Removed {n} items, {kb} KB freed.","cleanup.found":"{n} items, {kb} KB in all.","cleanup.intro":"The janitor clears what runs leave behind: temporary files, finished worktrees, stale refs and abandoned runs. You see the list before anything goes.","cleanup.kind.abandoned":"abandoned runs","cleanup.kind.refs":"stale refs","cleanup.kind.tmp":"temporary files","cleanup.kind.worktrees":"finished worktrees","cleanup.safe":"Only these items are removed. A worktree with uncommitted work is never touched.","cleanup.scan":"What can be cleaned?","cleanup.title":"Clean up","close":"Close","chat.resumeIn":"Continue it in a terminal:","commands.openWindow":"Open its window","commands.terminalOnly.device":"Terminal: it needs a device or a simulator next to you.","commands.terminalOnly.interactive":"Terminal: it asks you questions as it goes.","commands.terminalOnly.machine":"Terminal: it changes this installation or the machine.","commands.terminalOnly.self":"Terminal: it starts or stops this panel itself.","commands.destructive":"destructive","confirm":"Confirm","delete":"Delete","demo.banner":"Demo office: scripted activity, not your machine's data. Writes are off.","demo.chat.assistant":"Reading the screen before touching it.","demo.chat.done":"Done.","demo.chat.user":"{role}, what are you on?","demo.chatNote":"Demo chat: sample messages.","demo.doing.commit":"Writing the commit and the PR body","demo.doing.coordinating":"Coordinating the team","demo.doing.critic":"Looking for why the plan fails","demo.doing.dev":"Writing LoginView.swift","demo.doing.devcritic":"Running the build and tests","demo.doing.explore":"Reading the module map","demo.doing.plan":"Writing the plan","demo.doing.evidence":"Reading the Figma frames","demo.doing.reader":"Summarising a large file","demo.doing.report":"Writing the run report","demo.doing.review":"Reading the pull request","demo.doing.security":"Checking secrets and storage","demo.doing.session":"Answering in a plain session","demo.doing.waiting":"Asking you to approve the triage","demo.noWrites":"Demo office: nothing is sent.","demo.optFix":"Fix the findings","demo.optShip":"Commit as is","demo.question":"Two important findings. Fix them before the commit?","demo.runNote":"Demo run: results are not read from the machine.","demo.start":"Demo","demo.stop":"Exit demo","demo.task.init.issue":"Read the issue","demo.task.init.maturity":"Check the issue is ready","demo.task.init.worktree":"Create the worktree","demo.task.plan.explore":"Explore the affected files","demo.task.plan.write":"Write the plan","demo.task.plan.critic":"Plan critic review","demo.task.dev.test":"Write the failing test","demo.task.dev.code":"Fix LoginView dark mode","demo.task.dev.build":"Build and run the tests","demo.task.dev.critic":"Dev critic check","demo.task.review.models":"Three reviewers read the diff","demo.task.review.security":"Security audit","demo.task.review.triage":"Triage the findings","demo.task.commit.commit":"Commit","demo.task.commit.pr":"Open the pull request","demo.task.report.write":"Write the report","demo.task.report.channels":"Post the summary","demo.task.a.intake":"Read the request","demo.task.a.figma":"Figma design context","demo.task.a.swagger":"Swagger endpoints","demo.task.a.confluence":"Confluence pages","demo.task.a.repo":"Repository conventions","demo.task.a.concepts":"Platform-free concepts","demo.task.a.platform":"Per-platform pass","demo.task.a.render":"Render the document","demo.task.a.review":"Review the document","demo.task.a.publish":"Publish to Confluence","demo.task.a.report":"Report","demo.titleA":"Dark mode on the login screen","demo.titleB":"Payment retry analysis","demo.windowOffline":"Not connected: this window fills in when the page is opened with /multi-agent:office-on.","done":"Done","empty.body":"Nobody is at work. When a /multi-agent run or a Claude Code session is active, its team takes a table here.","empty.demo":"Watch the demo office","empty.title":"The office is quiet","error.generic":"Something went wrong.","event.demo":"Demo office started","event.done":"{name} is complete","event.join":"{role} joined {name}","event.phase":"{name}: phase {n}/{last} started, {phase}","event.seat-done":"{role} finished on {name}","event.table-new":"{name} opened a table in {repo}","event.waiting":"{name} is waiting for you","fx.done":"Run complete","fx.phase":"Phase {n}: {name}","hud.agents":"{n} agents working · {runs} runs · {sessions} sessions","hud.cost":"{v} today","hud.nothingWaiting":"Nothing waits for you.","hud.waiting":"{n} waiting","img.hidden":"[image not shown]","job.analysis":"Write the analysis","job.autopilot-run":"Run it on autopilot","job.check":"Review and start","job.diff-explain":"Explain a review's findings","job.estimate":"Estimate a ticket","job.give":"Give the job","job.doctor":"Health check","job.route-status":"Model routing status","job.scan":"Skill security scan","job.scenario-audit":"Scenario audit","job.review-analysis":"Analysis document review","jobHint.doctor":"Checks the installation and the services it reaches; changes nothing.","jobHint.route-status":"Reports where model routing is on and where recent calls went.","jobHint.scan":"Scans the installed skills for unsafe patterns; read-only.","jobHint.scenario-audit":"Checks a scenario file against the code: which scenarios are covered.","jobHint.review-analysis":"Reviews the analysis document of a Jira issue; nothing is posted.","job.graph":"Code graph","job.ios-coding-standard":"iOS coding standard","job.notInstalled":"not installed","job.pipeline":"Run the pipeline","job.postmortem":"Post-mortem of a run","job.preview":"{role} starts this in {repo}:","job.research":"Research a ticket","job.review":"Review a pull request","job.review-issue":"Check a GitHub issue","job.review-jira":"Check a Jira ticket","job.security-review":"Security review","job.solo":"Solo: works at a desk","job.soloNote":"A solo job: one person works at a desk in the open office.","job.startTitle":"Start this job?","job.started":"{role} took the job","job.team":"Team: meets in a room","job.teamNote":"A team job: the team meets in a room of that repository. Another run live there makes it wait.","job.test-gen":"Write the missing tests","job.unattended":"It runs in the background under the unattended permission profile, without asking for permissions; you follow it on the floor and in its chat.","jobHint.analysis":"A feature spec from the ticket and its sources; no code.","jobHint.autopilot-run":"The whole pipeline without questions, up to an open PR.","jobHint.diff-explain":"Maps a run's review findings to the diff lines.","jobHint.estimate":"Time per role from closed work, P25 to P75.","jobHint.graph":"Builds or reports the repository's code graph, no model calls.","jobHint.ios-coding-standard":"Audits a module against the 99 rules and plans the fixes.","jobHint.pipeline":"The whole team: plan, develop, review, commit and report, stopping where you have to decide.","jobHint.postmortem":"What happened in a run, from its transcripts.","jobHint.research":"Closes a run's open gaps from tracker, docs and repo.","jobHint.review":"Three reviewers read the PR; the findings come back as a report, nothing is posted.","jobHint.review-issue":"Grades the issue's readiness and lists the gaps.","jobHint.review-jira":"Grades the ticket's readiness and lists the gaps.","jobHint.security-review":"A threat-model review of the branch: OWASP and CWE categories, CVSS scores.","jobHint.test-gen":"Finds what has no test that would catch it, writes the tests and runs them.","lab.note":"Device tests (simulator or emulator) need a device at hand and stay terminal commands: /multi-agent:test.","ledger.byModel":"By model","ledger.byPhase":"By phase","ledger.byRepo":"By repository","ledger.byRun":"By run","ledger.month":"This month","ledger.name":"Name","ledger.notMeasured":"Not measured: {v}","ledger.note":"Estimated at list price from cost-table.json, not an invoice.","ledger.outside":"Outside the pipeline","ledger.source":"Source","ledger.today":"Today","ledger.total":"Total","ledger.unpriced":"{n} unpriced","ledger.verified":"verified {d}","ledger.week":"This week","list.empty":"No agent activity in the recent window.","list.limited":"Limited table: this host writes no subagent detail.","list.noBranch":"branch unknown","list.phaseHistory":"Phase history","list.room":"Room: {repo}","list.runDetail":"Run detail","list.showOnFloor":"Show on the floor","list.team":"Team of {name}","list.unmatched":"Unmatched: more than one run could own this session.","live.closed":"closed","live.demo":"demo","live.demoOnly":"demo, not connected","live.live":"live","live.notConnected":"not connected","live.offline":"offline","live.paused":"paused","live.polling":"polling","loading":"Loading","new.command":"Command: {c}","new.copyCmd":"Copy terminal command","new.devRun":"Full development run: analysis, plan, development, review, commit","new.enterTask":"Enter the task first.","new.launch":"Prepare background launch","new.launchBody":"Starts an unattended run in {repo}.","new.launchBtn":"Launch","new.launchTitle":"Launch","new.noRepo":"No repository yet. Add one below.","new.planBody":"The server wrote the request; start this command:","new.planTitle":"Launch plan","new.question":"Question {i} of {n} ({id}). Skip to let the run ask it.","new.repo":"Repository","new.request":"Launch request","new.requestNote":"The server validates and writes the request and returns the command that starts it; it never starts a session itself.","new.review":"Review","new.freeTextHint":"A Jira key, a GitHub issue link or repo#N, or one sentence describing the task.","new.workFilter":"Filter the list","new.workList":"Waiting for work: Jira and GitHub issues","new.search":"Search commands","new.skip":"Skip","new.step.command":"Command","new.step.launch":"Launch","new.step.questions":"Questions","new.step.task":"Task","new.summary":"Work item: {input}. Repository: {repo}.","new.taskPlaceholder":"Jira key, GitHub issue URL, repo#N, #N or one line of text","next":"Next","noAccess.body":"This page needs a fresh link: run /multi-agent:office-on in a terminal. A link works once, within 10 seconds, and a reload needs a new one.","noAccess.title":"No access","none":"None","notMeasured":"not measured","off":"off","on":"on","param.branch":"Branch (optional)","param.enum":"Choice","param.github-issue":"GitHub issue","param.jira-key":"Jira key","param.pickRun":"Pick a run","param.pull-request":"Pull request","param.repo-path":"Folder in the repository","param.scenario-audit.scenarios":"Scenario list (a CSV file in the repository)","placeholder.scenario-audit.scenarios":"docs/scenarios.csv","param.run-id":"Run","param.work-item":"Work item (Jira key, issue link or a sentence)","perm.count":"{n} host permission request(s)","perm.notForwarded":"Host permission prompts are not forwarded yet.","placeholder.branch":"feature/login","placeholder.github-issue":"https://github.com/org/repo/issues/7 or repo#7","placeholder.jira-key":"PROJ-123","placeholder.pull-request":"https://github.com/org/repo/pull/12 or repo#12","placeholder.repo-path":"Sources/Feature","placeholder.run-id":"PROJ-123","placeholder.work-item":"PROJ-123, repo#45 or a short task","prs.ask":"Ask about it","prs.copyReview":"Copy review command","prs.empty":"No open pull requests.","prs.notImplemented":"not implemented","prs.note":"A review run's findings and the verdict button are in that run's detail.","prs.reach":"{n} files depend on the {changed} it changes","prs.reachUnmeasured":"Reach not measured: {reason}","prs.review":"Have it reviewed","repos.absolute":"Write the full path, starting with /","repos.add":"Add","repos.addBody":"{n} becomes a repository runs can start in. Nothing else changes.","repos.addHint":"Add this checkout so runs can start in it","repos.addTitle":"Add {n}","repos.byPath":"Add by path","repos.empty":"No repository yet. Add one below: a checkout an earlier run worked in, or a path.","repos.missing":"Gone from disk","repos.none":"No repository yet","repos.path":"Repository path","repos.pathNote":"The folder must be a git checkout. The home folder and / are refused.","repos.pathPlaceholder":"/Users/you/my-app","repos.remove":"Remove from list","repos.removeBody":"Only the list entry goes. The folder is already gone; nothing on disk changes.","repos.removeTitle":"Remove {n} from the list","repos.suggested":"From earlier runs","role.assistant":"Agent","role.user":"You","room.accounting":"Accounting","room.archive":"Archive","room.kitchen":"Kitchen","room.lab":"Test lab","room.library":"Library","room.lobby":"Reception","room.lounge":"Lounge","room.mail":"Mail room","room.manager":"Manager's office","room.meeting":"Meeting floor","room.typeFree":"{type} · free","room.typeNameAnalysis":"Analysis room","room.typeNameDev":"Development room","room.typeSession":"Session · outside a pipeline","room.typeWith":"{type} · {command}","room.office":"Open office","room.restroom":"Restroom","room.server":"Server room","routines.deleteBody":"Deletes the routine command and its registry entry.","routines.deleteTitle":"Delete /multi-agent:{n}","routines.empty":"No saved routines.","routines.saveNote":"Saving a new routine needs the conversation, so it stays in the terminal.","run.analysis":"Analysis documents","run.confluence":"Confluence pages: {n}","run.decision":"Decision: {d} (blocking {b}, important {i})","run.diff":"Diff","run.diffLine":"{files} files, +{added} -{removed}","run.failed":"{n} failed","run.findings":"Review findings","run.findingsCount":"{n} findings ({source})","run.fix":"Fix:","run.noDiff":"No diff recorded.","run.noFindings":"No review findings recorded.","run.noTests":"No test summary recorded.","run.passed":"{n} passed","run.risk":"risk {v}","run.screenshots":"Screenshots","run.tests":"Tests","run.unreadable":"(not readable)","run.verdict":"Post review verdict","run.verdictHead":"Review verdict","run.verdictOff":"Available once the review has recorded findings.","run.verdictOn":"Enabled because the findings are shown above.","run.verdictRisk":"Posted with your own {p} credential on this machine. High risk.","run.verdictTitle":"Review verdict for {id}","services.contracts":"{n} API contracts","services.crash":"Crashlytics issue","services.crashLine":"{o} occurrences, {u} users","services.crashPh":"Crashlytics issue URL (console.firebase.google.com)","services.figmaNote":"Analysing this frame runs /multi-agent:analysis; use the ask box below or a terminal.","services.file":"Figma file key","services.filePh":"Figma file key","services.node":"Figma node id","services.nodePh":"Node id, e.g. 12:34","services.note":"Search across Confluence, a per-version Crashlytics trend and a Figma file browser have no client yet; ask an agent instead.","services.page":"Confluence page","services.pagePh":"Confluence page id or https URL","services.read":"Read","services.render":"Render frame","stack.alwaysOn":"always on","stack.change":"Change","stack.apply":"Apply","stack.changes":"Changes: {v}","stack.copyRefresh":"Copy refresh command","stack.dropped":"Not in the marketplace: {v}","stack.none":"No stack on yet","stack.unreadable":"Could not be read","stack.noManifest":"The marketplace manifest could not be read; the plugin list is the convention.","stack.noSkills":"No skills found locally.","stack.pick":"Pick a repository","stack.pickOne":"Select at least one stack.","stack.plugins":"Plugins","stack.restart":"Restart Claude Code in that repository to load the plugins. Copilot and Codex copies:","stack.stacks":"Stacks","stack.title":"Set stacks for {repo}","staff.busy":"at work","staff.free":"free","staff.idle":"waiting for work","staff.intro":"Everyone in the office and what they are doing. Pick someone to give them a job.","staff.officeTitle":"Office staff","staff.poolTitle":"Agent pool","staff.poolIntro":"They wait at the open office's desks and take their seat at a run's table when the run starts, if one of its phases uses their role.","staff.jobs":"Jobs they take","staff.noJobs":"No jobs for this person yet.","staff.openChat":"Open their chat","staff.openRoom":"Open {v}","staff.talkTo":"Talk to {v}","staff.workingOn":"Working on: {v}","card.room":"Room: {v}","card.agent":"Agent: {v}","card.tier.model":"Model: {v}","card.tier.fableOff":"Model: Opus (Fable is off)","card.tier.session":"Model: the main session's model","card.tier.script":"No model: runs a script","card.tier.none":"No model: shows the guide","card.now":"Now","card.free":"Free, at their desk","card.recent":"Recent work","card.noRecent":"No work on the floor yet.","card.state.now":"working","card.state.next":"waiting for their turn","card.state.done":"done","building.intro":"Every room of the building, who works there and what is going on. Pick a person to open their card.","building.nobody":"No one is stationed here.","building.tables":"{v} tables at work","building.people":"People","state.done":"done","state.idle":"idle","state.reading":"reading","state.spawning":"starting an agent","state.waiting":"waiting","state.writing":"writing","station.archive":"Archive","station.autopilot":"Autopilot","station.cleanup":"Cleanup","station.commands":"Commands","station.job":"Job","station.lab":"Test lab","station.ledger":"Ledger","station.list":"Team list","station.new":"Development · new run","station.newAnalysis":"Analysis · new run","station.office":"Office","station.prs":"PR mailbox","station.routines":"Routines","station.run":"Run","station.services":"Services","station.stack":"Skills","station.staff":"Team","station.tools":"Toolkit","station.work":"Quest board","stationHint.archive":"Every run, its log and post-mortem","stationHint.autopilot":"Turn the autopilot on or off and see its queue","stationHint.cleanup":"Clear what runs leave behind","stationHint.commands":"Every /multi-agent command","stationHint.job":"The jobs this person takes","stationHint.lab":"Tests written and checked","stationHint.ledger":"Tokens and estimated cost by run, repository, model and phase","stationHint.list":"The same office as text","stationHint.new":"/multi-agent: a task and a repository","stationHint.newAnalysis":"/multi-agent:analysis: a request and a repository","stationHint.office":"The floor with every team at work","stationHint.prs":"Pull requests on every GitHub account and Bitbucket","stationHint.routines":"Your saved /multi-agent routines","stationHint.run":"Results, findings, tests and the review verdict","stationHint.services":"Confluence, Crashlytics and Figma reads","stationHint.stack":"Stacks and plugins per repository","stationHint.staff":"Everyone in the office; give someone a job","stationHint.tools":"multi-agent-toolkit tools, called from here","stationHint.work":"Jira and GitHub issues by priority, with the maturity check","table.annexHint":"Go to the run's main room","table.corridor":"{name} works here too · main room: {repo}","table.limited":"{host}: limited","table.noPhase":"No phase","phaseState.done":"done","phaseState.now":"in progress","phaseState.todo":"waiting","taskState.completed":"done","taskState.in_progress":"in progress","taskState.pending":"waiting","mcp.error":"failed","mcp.ok":"done","mcp.running":"running","seat.mcp":"Recent MCP calls","seat.tasks":"Its task list","table.finished":"Finished: the team is wrapping up","table.now":"Now: {task}","table.ownerDoing":"{phase}: the orchestrator runs this step","table.phase":"Phase {n}/{last} {name}","table.session":"Session","table.unmatched":"unmatched","table.waiting":"Waiting for you","tools.badJson":"A JSON field is not valid JSON.","tools.call":"Call","tools.confirmTitle":"Call {name}?","tools.error":"The tool reported an error.","tools.notAllowlisted":"not on the allowlist","tools.notCallable":"Not callable from the panel: {v}","tools.notSet":"(not set)","tools.onePerLine":"One per line","tools.risk":"risk {v}","tools.running":"Running","tools.search":"Search tools","tools.terminalOnly":"terminal only","tools.version":"multi-agent-toolkit {v}, {n} tools. Updates with each pipeline update.","unit.hour":"h","unit.min":"m","update.gone":"Office is closed. Run /multi-agent:office-on to open it again.","update.page":"A newer Office is installed.","update.reload":"Reload","update.server":"Office was updated. Run /multi-agent:office-on to reopen it.","work.blockers":"Blockers","work.description":"Description","work.empty":"Nothing assigned.","work.noPriority":"no priority","work.score":"score {v}","work.start":"Start a run with this","work.unreadable":"could not be read","work.warnings":"Warnings","writes.branch":"writes a branch","writes.branch-pr":"opens a branch and PR","writes.issue-comment":"comments on the issue","writes.none":"reads only","writes.pr-comments":"comments on the PR","writesLong.branch":"It commits to a new branch in this repository.","writesLong.branch-pr":"It commits to a new branch and opens a pull request under your identity.","writesLong.issue-comment":"It posts a comment on the issue under your identity.","writesLong.pr-comments":"It posts review comments on the pull request under your identity.","zoom.in":"Zoom in","zoom.out":"Zoom out","role.orchestrator":"Orchestrator","role.reviewer":"Reviewer","role.security-auditor":"Security Auditor","role.ios-architect":"iOS Architect","role.android-architect":"Android Architect","role.backend-architect":"Backend Architect","role.explorer":"Explorer","role.planner":"Planner","role.clarifier":"Clarifier","role.test-gap-analyst":"Test Gap Analyst","role.reader":"Reader","role.librarian":"Librarian","role.sysadmin":"Sysadmin","role.mail-clerk":"Mail Clerk","role.janitor":"Janitor","new.terminalOnly":"A command with no one to hand it to runs from the terminal.","update.signedOut":"This page is signed out. Run /multi-agent:office-on to open it again.","cleanup.failed":"{n} item(s) could not be removed:","hud.costOffline":"Cost: not connected","hud.autopilotOffline":"Autopilot: not connected","cleanup.promptsNote":"Trimming instruction files stays a terminal command: /multi-agent:prune-prompts.","prune.title":"Old run logs","prune.intro":"Task log folders older than the age you pick. The audit trail, metrics and counters always stay; a run that can still be resumed and a folder written in the last minutes are spared.","prune.age":"Older than","prune.days":"{n} days","prune.scan":"See what would go","prune.found":"{n} task log folders, about {mb} MB","prune.more":"and {n} more","prune.safe":"Nothing is removed until you confirm.","prune.done":"Removed {n} task log folders, about {mb} MB freed.","station.keys":"Key cabinet","stationHint.keys":"Which credentials are held and whether they work; never a value","keys.intro":"Each service the pipeline can reach, by name. Values never leave the credential store.","keys.probe":"Check them live","keys.unavailable":"The credential inventory could not run on this machine.","keys.unmapped":"{n} services are not set up; /multi-agent:setup adds them.","keys.renew":"To renew or add one, run in a terminal:","keys.state.present":"held","keys.state.mapped-but-missing":"missing from the store","keys.state.unmapped":"not set up","keys.reach.not-probed":"not checked","keys.reach.reachable":"works","keys.reach.auth-rejected":"refused, renew it","keys.reach.unreachable":"unreachable (VPN?)","keys.reach.no-host-configured":"no host set","keys.reach.well-formed":"well formed","keys.reach.not-probeable":"cannot be checked","keys.reach.malformed":"malformed, renew it","keys.reach.no-credential":"nothing stored","keys.reach.probe-error":"the check failed","keys.reach.server-error":"the server answered with an error","keys.reach.tier-1-ready":"works","keys.reach.tier-2-ready":"works (fallback)","keys.reach.tier-1-no-grant":"works, needs a grant","keys.reach.unknown":"unknown answer","station.memory":"Memory","stationHint.memory":"What the pipeline learned per repository","memory.intro":"Per repository: the code graph, durable learnings, past review findings and session notes the learning loop holds.","memory.none":"No repository has a memory shelf yet.","memory.graphAge":"graph {n} days old","memory.noGraph":"no code graph","memory.counts":"{l} learnings · {f} past findings · {s} session notes","memory.emptyShelf":"Nothing is accumulating here: runs on this repository have not reached the report phase.","station.system":"System","stationHint.system":"CPU, memory, disk and what the pipeline uses","system.cpu":"CPU","system.load":"load {l} on {c} cores","system.memory":"Memory","system.disk":"Free disk","system.diskOf":"of {v}","system.pipeline":"Pipeline","system.sessions":"{n} sessions · {k} toolkit","system.rss":"{v} memory · logs {l} MB","system.warn.disk-low":"Under 10% of the disk is free: the janitor can clear old logs and worktrees.","system.warn.cpu-busy":"The CPU is saturated: parallel runs will be slow.","room.orientation":"Orientation","role.trainer":"Trainer","station.guide":"Guide","stationHint.guide":"How the office works: the rooms, how a job runs, what you can do here and what stays in the terminal","station.building":"Building","stationHint.building":"The building directory: every room, the people in it and what they are doing now","guide.intro":"Every room on this floor is a part of the pipeline. Click a room's window to use it, or a person to hand them work.","guide.show":"Show","guide.h.plan":"Floor plan","guide.h.flow":"How a job runs","guide.h.give":"Giving a job","guide.h.where":"Office or terminal","guide.h.security":"Security","guide.h.legend":"Signs","guide.room.lobby":"Start a development run or an analysis from a Jira or GitHub issue, or from free text.","guide.room.orientation":"This room: the guide you are reading.","guide.room.office":"Agents wait at their desks until a run calls their role. Solo jobs are done here.","guide.room.kitchen":"An agent called in for one step rests here for a moment, then goes back to their desk; the run's crew stays at the table.","guide.room.accounting":"Tokens and estimated cost per run, repository, model and phase.","guide.room.restroom":"Cleanup: temporary files, finished worktrees, stale refs, abandoned runs and old run logs. You see the list before anything goes.","guide.room.manager":"Autopilot and its switch, your saved routines, and the settings: output language, the fable rung, model routing.","guide.room.lab":"Test jobs: tests written for a repository and checked.","guide.room.library":"What the pipeline knows: stacks per repository, every command and what it has learned per repository.","guide.room.archive":"History: finished runs, their logs and postmortems.","guide.room.mail":"Pull requests waiting for you or opened by you, from every GitHub account and Bitbucket.","guide.room.server":"Outside lines: toolkit MCP tools, connected services, the key cabinet and the machine's resources.","guide.room.meeting":"One floor per repository: a Development room for /multi-agent, an Analysis room for /multi-agent:analysis.","guide.flow.1":"Agents wait at their desks in the open office.","guide.flow.2":"When a run needs a role, that person walks to the run's room on its repository's floor. A run that touches more repositories opens an annex desk on theirs.","guide.flow.3":"The table sign shows the phase, a bar that fills as its tasks finish and the task in progress: the same list as the terminal's task widget.","guide.flow.4":"An agent called in for one step rests in the kitchen when done, then returns to their desk; the crew stays seated until the run ends.","guide.flow.5":"A finished run stays on the floor for two minutes with its result, then the team leaves.","guide.pipeline.dev":"Development (/multi-agent): {v}","guide.pipeline.analysis":"Analysis (/multi-agent:analysis): {v}","guide.pipeline.mcp":"A session that uses the toolkit MCP directly gets its own desk, and its agent walks to the server racks while a tool runs.","guide.give.1":"Click a person to see the jobs they take; pick one, fill in the form and confirm.","guide.give.2":"A team job runs in a room on its repository's floor, a solo job at a desk. One team run per repository at a time.","guide.give.3":"When a run asks you something, a ! appears over its table and in the top bar.","guide.where.1":"Jobs: the model does the work and reports (reviews, analyses, test plans).","guide.where.2":"Windows: what you read here, and actions that show a preview and run only on your confirmation (autopilot, stack, routines, cleanup, settings).","guide.where.3":"Terminal only: work that is interactive or changes the installation (setup, update, sync, uninstall). The commands window says why for each one.","guide.security.1":"The server listens on 127.0.0.1 only and runs until /multi-agent:office-off stops it.","guide.security.2":"The access token is held in this page's memory, never in a URL, a cookie or browser storage.","guide.security.3":"Actions that change the machine or start work show a preview first and run only on your confirmation; every write is recorded.","guide.security.4":"No credential reaches this page: the key cabinet shows names and states, and renewal happens in the terminal with /multi-agent:setup.","guide.security.5":"Review jobs report here and post nothing; the demo plays a made-up day and changes nothing.","guide.legend.done":"Phase finished","guide.legend.now":"Phase in progress; it fills as its tasks finish","guide.legend.pending":"Phase not started","guide.legend.you":"A run is waiting for you","guide.legend.ask":"An agent asked a question","guide.legend.spawn":"An agent is starting","guide.legend.cloud":"A cloud over someone at work says what they are doing; click it for the detail.","role.developer":"Developer","role.plan-critic":"Plan Critic","role.dev-critic":"Dev Critic","role.committer":"Committer","role.reporter":"Reporter","chat.askedInTerminal":"This session is asking you a question in its terminal. Answer it there; the panel answers only questions a run leaves for it.","table.freeText":"Free text","table.prOpened":"PR #{n} opened","table.waitingFor.local-test":"Waiting for you: test it locally?","table.waitingFor.user-channels-choice":"Waiting for you: where to report","table.waitingFor.maturity":"Waiting for you: the issue is not ready","table.waitingFor.attended-reply":"Waiting for your reply","table.waitingFor.question":"Waiting for your answer here","table.waitingFor.terminal":"Asking you in the terminal","event.guide":"New here? The guide is in the orientation room, next to reception.","table.crewDone":"done with {phase}","table.headWaiting":"waiting for your answer","table.headQuiet":"no recent activity in its session","table.crewNext":"waiting for {phase}","run.report":"Report","run.channel.pr":"PR description","run.channel.jira":"Jira","run.channel.confluence":"Confluence","run.channel.wiki":"Wiki","run.channel.issue":"GitHub issue","run.channelState.posted":"posted","run.channelState.skipped":"skipped","run.channelState.failed":"failed","memory.buildGraph":"Build the code graph","memory.refreshGraph":"Refresh the code graph","station.settings":"Settings","stationHint.settings":"Output language, the fable rung and model routing","settings.intro":"Each switch runs what its terminal command runs, after a preview.","settings.language":"Output language","settings.languageHint":"The language the pipeline writes to you in: reports, PR and Jira comments, this office.","settings.model":"Fable rung","settings.modelHint":"Whether runs may use Fable at the top of the model ladder (/multi-agent:model).","settings.route":"Model routing","settings.routeHint":"Whether calls are routed by the saved rules (/multi-agent:route-on and route-off).","settings.value.language.en":"English","settings.value.language.tr":"Türkçe","settings.value.model.on":"On","settings.value.model.off":"Off","settings.value.route.on":"On","settings.value.route.off":"Off","settings.change":"{from} → {to}","settings.languageNote":"Command descriptions in the CLI picker change on the next session start; run /multi-agent:office-on again to see this page in the new language.","settings.terminalNote":"Routing rules, free providers and prompt language stay in the terminal.","settings.freeChain":"This also brings back the free provider chain you saved earlier.","settings.freeChainTraining":"This also brings back the free provider chain you saved earlier, including providers that may train on what they are sent."},"tr":{"app.title":"Ofis","archive.empty":"Henüz kayıtlı koşu yok.","archive.log":"Günlük","archive.postmortem":"Post-mortem iste","ask.copy":"Komutu kopyala","ask.handOff":"Birine iş ver","ask.label":"Ajana sor","ask.note":"Panelden soru başlatmak henüz yok, çünkü serbest metindeki linkleri başlatma girdisi kabul etmiyor. Komutu kopyala, terminalde çalıştır.","ask.placeholder":"Bu ekranla ilgili ajana sor","autopilot.ceiling":"tavan {v}","autopilot.switch":"Otopilotu aç ya da kapat","autopilot.onHint":"Aşağıdaki repoları izliyor, aynı anda en fazla {n} iş alıyor.","autopilot.offHint":"İzlenecek repoları seç, sonra aç.","autopilot.noRepoHint":"Önce terminalden bir repo ekle; sonra buradan açılabilir.","autopilot.ofSlots":"en fazla {n} aynı anda","autopilot.reposTitle":"İzlenen repolar","autopilot.pickOn":"İzlenecek repoları değiştirmek için yeni bir seçim yap.","autopilot.saveOnly":"Seçimi kaydet, başlatma","autopilot.saveTitle":"Otopilot seçimini kaydet","autopilot.stopNowBtn":"Hemen durdur","autopilot.stopNowTitle":"Otopilotu hemen durdur","autopilot.addInTerminal":"Yeni repo terminalden eklenir, çünkü kaynaklarını ve etiketini sorar:","autopilot.configureOnly":"Yalnızca seçimi kaydet, iş planlama","autopilot.credsBad":"Kimlik bilgileri sorunlu, iş planlanmayacak","autopilot.credsOk":"Kimlik bilgileri okunuyor","autopilot.drop":"Çıkar: {v}","autopilot.keep":"Kalsın: {v}","autopilot.noRepo":"Yapılandırılmış repo yok.","autopilot.off":"Otopilot kapalı","autopilot.offDrain":"Süren iş biter, yeni iş alınmaz.","autopilot.offNow":"Süren işler durdurulur, koşuları yarıda bırakıldı sayılır.","autopilot.offTitle":"Otopilotu kapat","autopilot.on":"Otopilot açık","autopilot.onTitle":"Otopilotu aç","autopilot.pick":"İzlenecek repoları seç.","autopilot.pickOne":"En az bir repo seç.","autopilot.queued":"Kuyrukta","autopilot.running":"Çalışıyor","autopilot.slots":"Slot","autopilot.state":"Durum","autopilot.stopNow":"Süren işleri de şimdi durdur","autopilot.today":"Bugün","autopilot.turnOff":"Kapat","autopilot.turnOn":"Aç","autopilot.unknown":"Otopilot ?","back":"Geri","bot.autopilot":"Otopilot","bot.doing":"Kuyruğu izliyor","cancel":"Vazgeç","chat.answer":"Cevapla","chat.answerTitle":"{id} cevabı","chat.answered":"Cevaplandı","chat.kill":"Öldür","chat.killBody":"Oturum durur, worktree silinir. Uzak branch ve loglar kalır.","chat.killTitle":"{id} koşusunu öldür","chat.noResult":"Henüz sonuç yok.","chat.noTranscript":"Bu koltuğun kaydı yok.","chat.nowIn":"şu an faz {n}","chat.older":"Eskileri yükle","chat.pickFirst":"Önce bir seçenek seç.","chat.queued":"Sıraya alındı","chat.queuedReplaced":"Sıraya alındı (öncekinin yerine)","chat.replaces":"Okunmamış talimatın yerine geçer:","chat.resume":"Devam ettir","chat.resumeBody":"Bu koşuyu arka planda sürdürecek planı döndürür.","chat.resumePlan":"Devam planı","chat.resumeTitle":"{id} koşusunu sürdür","chat.runGone":"Bu koşu artık ofiste değil; buradan ona bir şey gönderilemez.","chat.send":"Gönder: {v}","chat.sendBtn":"Gönder","chat.steer":"Yönlendir","chat.steerLabel":"Yönlendirme talimatı","chat.steerPlaceholder":"Sonraki faz için talimat (steer)","chat.steerTitle":"{id} koşusunu yönlendir","chat.steerWhen":"Sonraki fazın girişinde uygulanır","chat.toolResult":"Araç sonucu","cleanup.done":"{n} öğe silindi, {kb} KB boşaldı.","cleanup.found":"{n} öğe, toplam {kb} KB.","cleanup.intro":"Temizlikçi koşuların geride bıraktıklarını toplar: geçici dosyalar, biten worktree'ler, eski ref'ler ve terk edilmiş koşular. Bir şey silinmeden önce listeyi görürsün.","cleanup.kind.abandoned":"terk edilmiş koşular","cleanup.kind.refs":"eski ref'ler","cleanup.kind.tmp":"geçici dosyalar","cleanup.kind.worktrees":"biten worktree'ler","cleanup.safe":"Yalnızca bu öğeler silinir. Commit'lenmemiş işi olan bir worktree'ye asla dokunulmaz.","cleanup.scan":"Neler temizlenebilir?","cleanup.title":"Temizlik","close":"Kapat","chat.resumeIn":"Terminalde sürdürmek için:","commands.openWindow":"Penceresini aç","commands.terminalOnly.device":"Terminal: yanında bir cihaz ya da simülatör ister.","commands.terminalOnly.interactive":"Terminal: çalışırken sana soru sorar.","commands.terminalOnly.machine":"Terminal: bu kurulumu ya da makineyi değiştirir.","commands.terminalOnly.self":"Terminal: bu panelin kendisini açar ya da kapatır.","commands.destructive":"yıkıcı","confirm":"Onayla","delete":"Sil","demo.banner":"Demo ofis: senaryolu hareket, makinendeki veri değil. Yazma kapalı.","demo.chat.assistant":"Dokunmadan önce ekranı okuyorum.","demo.chat.done":"Bitti.","demo.chat.user":"{role}, ne üzerindesin?","demo.chatNote":"Demo sohbet: örnek mesajlar.","demo.doing.commit":"Commit ve PR metnini yazıyor","demo.doing.coordinating":"Ekibi yönetiyor","demo.doing.critic":"Planın neden çökeceğini arıyor","demo.doing.dev":"LoginView.swift yazıyor","demo.doing.devcritic":"Build ve testleri koşuyor","demo.doing.explore":"Modül haritasını okuyor","demo.doing.plan":"Planı yazıyor","demo.doing.evidence":"Figma çerçevelerini okuyor","demo.doing.reader":"Büyük bir dosyayı özetliyor","demo.doing.report":"Koşu raporunu yazıyor","demo.doing.review":"Pull request'ı okuyor","demo.doing.security":"Sırları ve saklamayı kontrol ediyor","demo.doing.session":"Düz bir oturumda cevap veriyor","demo.doing.waiting":"Triyaj onayını soruyor","demo.noWrites":"Demo ofis: hiçbir şey gönderilmez.","demo.optFix":"Bulguları düzelt","demo.optShip":"Olduğu gibi commit et","demo.question":"İki önemli bulgu var. Commit'ten önce düzeltilsin mi?","demo.runNote":"Demo koşu: sonuçlar makineden okunmaz.","demo.start":"Demo","demo.stop":"Demodan çık","demo.task.init.issue":"Issue'yu oku","demo.task.init.maturity":"Issue'nun hazır olduğunu kontrol et","demo.task.init.worktree":"Worktree aç","demo.task.plan.explore":"Etkilenen dosyaları tara","demo.task.plan.write":"Planı yaz","demo.task.plan.critic":"Plan eleştirmeni incelemesi","demo.task.dev.test":"Önce başarısız olan testi yaz","demo.task.dev.code":"LoginView'un karanlık modunu düzelt","demo.task.dev.build":"Derle ve testleri koş","demo.task.dev.critic":"Geliştirme eleştirmeni kontrolü","demo.task.review.models":"Üç inceleyici diff'i okuyor","demo.task.review.security":"Güvenlik denetimi","demo.task.review.triage":"Bulguları ayıkla","demo.task.commit.commit":"Commit","demo.task.commit.pr":"Pull request aç","demo.task.report.write":"Raporu yaz","demo.task.report.channels":"Özeti paylaş","demo.task.a.intake":"İsteği oku","demo.task.a.figma":"Figma tasarım bağlamı","demo.task.a.swagger":"Swagger uç noktaları","demo.task.a.confluence":"Confluence sayfaları","demo.task.a.repo":"Repo konvansiyonları","demo.task.a.concepts":"Platformdan bağımsız kavramlar","demo.task.a.platform":"Platform başına geçiş","demo.task.a.render":"Dokümanı oluştur","demo.task.a.review":"Dokümanı incele","demo.task.a.publish":"Confluence'a yayınla","demo.task.a.report":"Rapor","demo.titleA":"Giriş ekranında karanlık mod","demo.titleB":"Ödeme tekrar deneme analizi","demo.windowOffline":"Bağlı değil: bu pencere sayfa /multi-agent:office-on ile açılınca dolar.","done":"Tamam","empty.body":"Şu an kimse çalışmıyor. Bir /multi-agent koşusu ya da Claude Code oturumu başlayınca ekibi burada bir masaya oturur.","empty.demo":"Demo ofisi izle","empty.title":"Ofis sessiz","error.generic":"Bir şey ters gitti.","event.demo":"Demo ofis başladı","event.done":"{name} tamamlandı","event.join":"{role}, {name} ekibine katıldı","event.phase":"{name}: {n}/{last}. faz başladı ({phase})","event.seat-done":"{role}, {name} işini bitirdi","event.table-new":"{name}, {repo} odasında masa açtı","event.waiting":"{name} seni bekliyor","fx.done":"Koşu tamamlandı","fx.phase":"Faz {n}: {name}","hud.agents":"{n} ajan çalışıyor · {runs} koşu · {sessions} oturum","hud.cost":"bugün {v}","hud.nothingWaiting":"Seni bekleyen bir şey yok.","hud.waiting":"{n} bekliyor","img.hidden":"[görsel gösterilmedi]","job.analysis":"Analiz yaz","job.autopilot-run":"Otopilotta koştur","job.check":"Gözden geçir ve başlat","job.diff-explain":"Review bulgularını açıkla","job.estimate":"Ticket için tahmin","job.give":"İşi ver","job.graph":"Kod grafı","job.ios-coding-standard":"iOS kodlama standardı","job.notInstalled":"kurulu değil","job.pipeline":"Pipeline'ı koştur","job.postmortem":"Koşunun post-mortem'i","job.preview":"{role}, {repo} reposunda şunu başlatır:","job.research":"Ticket'ı araştır","job.review":"Pull request incelet","job.review-issue":"GitHub issue'yu kontrol et","job.review-jira":"Jira ticket'ını kontrol et","job.security-review":"Güvenlik incelemesi","job.solo":"Tek kişi: masada çalışır","job.soloNote":"Tek kişilik iş: bir kişi açık ofiste bir masada çalışır.","job.startTitle":"Bu iş başlasın mı?","job.started":"{role} işi aldı","job.team":"Ekip: odada toplanır","job.teamNote":"Ekip işi: ekip o reponun bir odasında toplanır. Orada canlı başka bir koşu varsa bekler.","job.test-gen":"Eksik testleri yaz","job.unattended":"Arka planda, gözetimsiz izin profiliyle ve izin sormadan çalışır; ilerleyişi katta ve sohbetinde izlersin.","jobHint.analysis":"Ticket ve kaynaklarından özellik spesifikasyonu; kod yok.","jobHint.autopilot-run":"Bütün pipeline soru sormadan, açık bir PR'a kadar.","jobHint.diff-explain":"Bir koşunun review bulgularını diff satırlarına eşler.","jobHint.estimate":"Kapanmış işlerden rol başına süre, P25-P75.","jobHint.graph":"Reponun kod grafını kurar ya da raporlar; model çağrısı yok.","jobHint.ios-coding-standard":"Bir modülü 99 kurala göre denetler, düzeltme planı çıkarır.","jobHint.pipeline":"Bütün ekip: plan, geliştirme, review, commit ve rapor; karar gereken yerde durur.","jobHint.postmortem":"Bir koşuda ne olduğunu transcript'lerinden çıkarır.","jobHint.research":"Bir koşunun açık boşluklarını tracker, doküman ve repodan kapatır.","jobHint.review":"Üç inceleyici PR'ı okur; bulgular rapor olarak döner, hiçbir şey gönderilmez.","jobHint.review-issue":"Issue'nun hazır olup olmadığını puanlar, eksikleri listeler.","jobHint.review-jira":"Ticket'ın hazır olup olmadığını puanlar, eksikleri listeler.","jobHint.security-review":"Branch'in tehdit modeli incelemesi: OWASP ve CWE kategorileri, CVSS puanları.","jobHint.test-gen":"Yakalayacak testi olmayan yerleri bulur, testleri yazar ve koşturur.","lab.note":"Cihaz testleri (simülatör ya da emülatör) elde bir cihaz ister ve terminal komutu olarak kalır: /multi-agent:test.","ledger.byModel":"Modele göre","ledger.byPhase":"Faza göre","ledger.byRepo":"Repoya göre","ledger.byRun":"Koşuya göre","ledger.month":"Bu ay","ledger.name":"Ad","ledger.notMeasured":"Ölçülmedi: {v}","ledger.note":"cost-table.json liste fiyatıyla tahmin, fatura değil.","ledger.outside":"Pipeline dışı","ledger.source":"Kaynak","ledger.today":"Bugün","ledger.total":"Toplam","ledger.unpriced":"{n} fiyatsız","ledger.verified":"doğrulama {d}","ledger.week":"Bu hafta","list.empty":"Son dakikalarda ajan hareketi yok.","list.limited":"Kısıtlı masa: bu araç alt ajan ayrıntısı yazmıyor.","list.noBranch":"branch bilinmiyor","list.phaseHistory":"Faz geçmişi","list.room":"Oda: {repo}","list.runDetail":"Koşu ayrıntısı","list.showOnFloor":"Ofiste göster","list.team":"{name} ekibi","list.unmatched":"Eşlenemedi: bu oturum birden çok koşuya ait olabilir.","live.closed":"kapalı","live.demo":"demo","live.demoOnly":"demo, bağlı değil","live.live":"canlı","live.notConnected":"bağlı değil","live.offline":"çevrimdışı","live.paused":"duraklatıldı","live.polling":"yoklanıyor","loading":"Yükleniyor","new.command":"Komut: {c}","new.copyCmd":"Terminal komutunu kopyala","new.devRun":"Tam geliştirme koşusu: analiz, plan, geliştirme, review, commit","new.enterTask":"Önce görevi yaz.","new.launch":"Arka plan başlatmayı hazırla","new.launchBody":"{repo} içinde gözetimsiz bir koşu başlatır.","new.launchBtn":"Başlat","new.launchTitle":"Başlat","new.noRepo":"Henüz repo yok. Aşağıdan ekle.","new.planBody":"Sunucu isteği yazdı; şu komutu başlat:","new.planTitle":"Başlatma planı","new.question":"Soru {i}/{n} ({id}). Atla dersen koşu kendisi sorar.","new.repo":"Repo","new.request":"Başlatma isteği","new.requestNote":"Sunucu isteği doğrulayıp yazar ve başlatacak komutu döndürür; oturumu kendisi başlatmaz.","new.review":"Gözden geçir","new.freeTextHint":"Bir Jira anahtarı, GitHub issue linki ya da repo#N; veya işi anlatan tek bir cümle.","new.workFilter":"Listeyi süz","new.workList":"Bekleyen işler: Jira ve GitHub issue'ları","new.search":"Komut ara","new.skip":"Atla","new.step.command":"Komut","new.step.launch":"Başlat","new.step.questions":"Sorular","new.step.task":"Görev","new.summary":"İş: {input}. Repo: {repo}.","new.taskPlaceholder":"Jira anahtarı, GitHub issue linki, repo#N, #N ya da tek satır metin","next":"İleri","noAccess.body":"Bu sayfa yeni bir link ister: terminalde /multi-agent:office-on çalıştır. Link bir kez ve 10 saniye içinde çalışır; yenileme yeni link ister.","noAccess.title":"Erişim yok","none":"Yok","notMeasured":"ölçülmedi","off":"kapalı","on":"açık","param.branch":"Branch (isteğe bağlı)","param.enum":"Seçim","param.github-issue":"GitHub issue","param.jira-key":"Jira key","param.pickRun":"Bir koşu seç","param.pull-request":"Pull request","param.repo-path":"Repodaki klasör","param.scenario-audit.scenarios":"Senaryo listesi (repodaki bir CSV dosyası)","placeholder.scenario-audit.scenarios":"docs/scenarios.csv","param.run-id":"Koşu","param.work-item":"İş (Jira key, issue linki ya da bir cümle)","perm.count":"{n} izin isteği","perm.notForwarded":"Araç izin soruları henüz buraya gelmiyor.","placeholder.branch":"feature/login","placeholder.github-issue":"https://github.com/org/repo/issues/7 ya da repo#7","placeholder.jira-key":"PROJ-123","placeholder.pull-request":"https://github.com/org/repo/pull/12 ya da repo#12","placeholder.repo-path":"Sources/Feature","placeholder.run-id":"PROJ-123","placeholder.work-item":"PROJ-123, repo#45 ya da kısa bir görev","prs.ask":"Hakkında sor","prs.copyReview":"Review komutunu kopyala","prs.empty":"Açık PR yok.","prs.notImplemented":"henüz yok","prs.note":"Review koşusunun bulguları ve karar butonu o koşunun ayrıntısında.","prs.reach":"Değiştirdiği {changed} dosyaya {n} dosya bağlı","prs.reachUnmeasured":"Etki ölçülmedi: {reason}","prs.review":"İncelet","repos.absolute":"Tam yolu yaz, / ile başlasın","repos.add":"Ekle","repos.addBody":"{n} koşu başlatılabilen repolara eklenir. Başka hiçbir şey değişmez.","repos.addHint":"Bu repoyu ekle, koşular burada başlayabilsin","repos.addTitle":"{n} eklensin","repos.byPath":"Yol ile ekle","repos.empty":"Henüz repo yok. Aşağıdan ekle: önceki bir koşunun çalıştığı repo ya da bir yol.","repos.missing":"Diskte artık yok","repos.none":"Henüz repo yok","repos.path":"Repo yolu","repos.pathNote":"Klasör bir git reposu olmalı. Ana klasör ve / kabul edilmez.","repos.pathPlaceholder":"/Users/sen/uygulama","repos.remove":"Listeden çıkar","repos.removeBody":"Yalnızca liste kaydı silinir. Klasör zaten yok; diskte hiçbir şey değişmez.","repos.removeTitle":"{n} listeden çıkarılsın","repos.suggested":"Önceki koşulardan","role.assistant":"Ajan","role.user":"Sen","room.accounting":"Muhasebe","room.archive":"Arşiv","room.kitchen":"Mutfak","room.lab":"Test laboratuvarı","room.library":"Kütüphane","room.lobby":"Resepsiyon","room.lounge":"Dinlenme","room.mail":"Posta odası","room.manager":"Yönetici odası","room.meeting":"Toplantı katı","room.typeFree":"{type} · boş","room.typeNameAnalysis":"Analiz Odası","room.typeNameDev":"Geliştirme Odası","room.typeSession":"Oturum · pipeline dışı","room.typeWith":"{type} · {command}","room.office":"Açık ofis","room.restroom":"Tuvalet","room.server":"Sunucu odası","routines.deleteBody":"Rutin komutunu ve kaydını siler.","routines.deleteTitle":"/multi-agent:{n} silinsin","routines.empty":"Kayıtlı rutin yok.","routines.saveNote":"Yeni rutin kaydı konuşmaya ihtiyaç duyar, bu yüzden terminalde kalır.","run.analysis":"Analiz dokümanları","run.confluence":"Confluence sayfası: {n}","run.decision":"Karar: {d} (engelleyen {b}, önemli {i})","run.diff":"Diff","run.diffLine":"{files} dosya, +{added} -{removed}","run.failed":"{n} başarısız","run.findings":"Review bulguları","run.findingsCount":"{n} bulgu ({source})","run.fix":"Düzeltme:","run.noDiff":"Diff kaydı yok.","run.noFindings":"Review bulgusu kaydı yok.","run.noTests":"Test özeti kaydı yok.","run.passed":"{n} geçti","run.risk":"risk {v}","run.screenshots":"Ekran görüntüleri","run.tests":"Testler","run.unreadable":"(okunamadı)","run.verdict":"Review kararını gönder","run.verdictHead":"Review kararı","run.verdictOff":"Review bulgu kaydedince açılır.","run.verdictOn":"Bulgular yukarıda göründüğü için açık.","run.verdictRisk":"Bu makinedeki kendi {p} kimliğinle gönderilir. Yüksek risk.","run.verdictTitle":"{id} review kararı","services.contracts":"{n} API sözleşmesi","services.crash":"Crashlytics sorunu","services.crashLine":"{o} tekrar, {u} kullanıcı","services.crashPh":"Crashlytics sorun linki (console.firebase.google.com)","services.figmaNote":"Bu frame'i analiz etmek /multi-agent:analysis koşturur; aşağıdaki soru kutusunu ya da terminali kullan.","services.file":"Figma dosya anahtarı","services.filePh":"Figma dosya anahtarı","services.node":"Figma düğüm kimliği","services.nodePh":"Node id, örn. 12:34","services.note":"Confluence araması, sürüm bazlı Crashlytics eğilimi ve Figma dosya gezgini için istemci henüz yok; bir ajana sor.","services.page":"Confluence sayfası","services.pagePh":"Confluence sayfa id'si ya da https linki","services.read":"Oku","services.render":"Frame'i çiz","stack.alwaysOn":"hep açık","stack.change":"Değiştir","stack.apply":"Uygula","stack.changes":"Değişiklik: {v}","stack.copyRefresh":"Yenileme komutunu kopyala","stack.dropped":"Marketplace'te yok: {v}","stack.none":"Henüz stack açık değil","stack.unreadable":"Okunamadı","stack.noManifest":"Marketplace manifest'i okunamadı; eklenti listesi varsayılandır.","stack.noSkills":"Yerelde skill bulunamadı.","stack.pick":"Repo seç","stack.pickOne":"En az bir stack seç.","stack.plugins":"Eklentiler","stack.restart":"Eklentilerin yüklenmesi için o repoda Claude Code'u yeniden başlat. Copilot ve Codex kopyaları:","stack.stacks":"Stack'ler","stack.title":"{repo} için stack'ler","staff.busy":"çalışıyor","staff.free":"boşta","staff.idle":"iş bekliyor","staff.intro":"Ofisteki herkes ve ne yaptıkları. Birine tıkla, iş ver.","staff.officeTitle":"Ofis çalışanları","staff.poolTitle":"Ajan havuzu","staff.poolIntro":"Açık ofisteki masalarda beklerler; koşu başlayınca, fazlarından biri rollerini kullanıyorsa o koşunun masasına geçerler.","staff.jobs":"Aldığı işler","staff.noJobs":"Bu kişinin henüz işi yok.","staff.openChat":"Sohbetini aç","staff.openRoom":"{v} aç","staff.talkTo":"{v} ile konuş","staff.workingOn":"Şu an: {v}","card.room":"Oda: {v}","card.agent":"Ajan: {v}","card.tier.model":"Model: {v}","card.tier.fableOff":"Model: Opus (Fable kapalı)","card.tier.session":"Model: ana oturumun modeli","card.tier.script":"Model yok: bir betik çalıştırır","card.tier.none":"Model yok: rehberi gösterir","card.now":"Şu an","card.free":"Boşta, masasında","card.recent":"Son işler","card.noRecent":"Katta henüz işi yok.","card.state.now":"çalışıyor","card.state.next":"sırasını bekliyor","card.state.done":"bitti","building.intro":"Binanın her odası, orada kimin çalıştığı ve neler olduğu. Kartını açmak için birine tıkla.","building.nobody":"Burada sürekli çalışan kimse yok.","building.tables":"{v} masa çalışıyor","building.people":"Kişiler","state.done":"bitti","state.idle":"boşta","state.reading":"okuyor","state.spawning":"ajan başlatıyor","state.waiting":"bekliyor","state.writing":"yazıyor","station.archive":"Arşiv","station.autopilot":"Otopilot","station.cleanup":"Temizlik","station.commands":"Komutlar","station.job":"İş","station.lab":"Test lab","station.ledger":"Muhasebe","station.list":"Ekip listesi","station.new":"Geliştirme · yeni koşu","station.newAnalysis":"Analiz · yeni koşu","station.office":"Ofis","station.prs":"PR kutusu","station.routines":"Rutinler","station.run":"Koşu","station.services":"Servisler","station.stack":"Skill'ler","station.staff":"Ekip","station.tools":"Araçlar","station.work":"Görev panosu","stationHint.archive":"Her koşu, günlüğü ve post-mortem'i","stationHint.autopilot":"Otopilotu aç, kapat, kuyruğunu gör","stationHint.cleanup":"Koşuların geride bıraktıklarını temizle","stationHint.commands":"Bütün /multi-agent komutları","stationHint.job":"Bu kişinin aldığı işler","stationHint.lab":"Testler yazılır ve doğrulanır","stationHint.ledger":"Koşu, repo, model ve faza göre token ve tahmini maliyet","stationHint.list":"Aynı ofis, metin olarak","stationHint.new":"/multi-agent: görev ve repo seç","stationHint.newAnalysis":"/multi-agent:analysis: istek ve repo seç","stationHint.office":"Çalışan bütün ekipler","stationHint.prs":"Tüm GitHub hesapları ve Bitbucket'taki PR'lar","stationHint.routines":"Kaydettiğin /multi-agent rutinleri","stationHint.run":"Sonuçlar, bulgular, testler ve review kararı","stationHint.services":"Confluence, Crashlytics ve Figma okuma","stationHint.stack":"Repo başına stack ve eklentiler","stationHint.staff":"Ofisteki herkes; birine iş ver","stationHint.tools":"multi-agent-toolkit araçları, buradan çağrılır","stationHint.work":"Öncelik sırasıyla Jira ve GitHub işleri, olgunluk kontrolüyle","table.annexHint":"Koşunun ana odasına git","table.corridor":"{name} burada da çalışıyor · ana oda: {repo}","table.limited":"{host}: kısıtlı","table.noPhase":"Faz yok","phaseState.done":"bitti","phaseState.now":"sürüyor","phaseState.todo":"bekliyor","taskState.completed":"bitti","taskState.in_progress":"sürüyor","taskState.pending":"bekliyor","mcp.error":"hata","mcp.ok":"tamam","mcp.running":"sürüyor","seat.mcp":"Son MCP çağrıları","seat.tasks":"Görev listesi","table.finished":"Bitti: ekip toparlanıyor","table.now":"Şu an: {task}","table.ownerDoing":"{phase}: bu adımı orkestratör yürütüyor","table.phase":"Faz {n}/{last} {name}","table.session":"Oturum","table.unmatched":"eşlenemedi","table.waiting":"Seni bekliyor","tools.badJson":"Bir JSON alanı geçersiz.","tools.call":"Çağır","tools.confirmTitle":"{name} çağrılsın mı?","tools.error":"Araç hata bildirdi.","tools.notAllowlisted":"izin listesinde değil","tools.notCallable":"Panelden çağrılamaz: {v}","tools.notSet":"(boş)","tools.onePerLine":"Satır başına bir","tools.risk":"risk {v}","tools.running":"Çalışıyor","tools.search":"Araç ara","tools.terminalOnly":"yalnızca terminal","tools.version":"multi-agent-toolkit {v}, {n} araç. Her pipeline güncellemesiyle kendiliğinden ilerler.","unit.hour":"sa","unit.min":"dk","update.gone":"Ofis kapandı. Yeniden açmak için /multi-agent:office-on yaz.","update.page":"Ofisin yeni sürümü kuruldu.","update.reload":"Yenile","update.server":"Ofis güncellendi. Yeniden açmak için /multi-agent:office-on yaz.","work.blockers":"Engeller","work.description":"Açıklama","work.empty":"Atanmış iş yok.","work.noPriority":"öncelik yok","work.score":"puan {v}","work.start":"Bununla koşu başlat","work.unreadable":"okunamadı","work.warnings":"Uyarılar","writes.branch":"branch yazar","writes.branch-pr":"branch ve PR açar","writes.issue-comment":"issue'ya yorum yazar","writes.none":"yalnızca okur","writes.pr-comments":"PR'a yorum yazar","writesLong.branch":"Bu repoda yeni bir branch'e commit atar.","writesLong.branch-pr":"Yeni bir branch'e commit atar ve senin kimliğinle pull request açar.","writesLong.issue-comment":"Senin kimliğinle issue'ya yorum yazar.","writesLong.pr-comments":"Senin kimliğinle pull request'e inceleme yorumları yazar.","zoom.in":"Yakınlaştır","zoom.out":"Uzaklaştır","role.orchestrator":"Orkestratör","role.reviewer":"İnceleyici","role.security-auditor":"Güvenlik Denetçisi","role.ios-architect":"iOS Mimarı","role.android-architect":"Android Mimarı","role.backend-architect":"Backend Mimarı","role.explorer":"Kaşif","role.planner":"Planlamacı","role.clarifier":"Netleştirici","role.test-gap-analyst":"Test Açığı Analisti","role.reader":"Okuyucu","role.librarian":"Kütüphaneci","role.sysadmin":"Sistem Yöneticisi","role.mail-clerk":"Posta Memuru","role.janitor":"Temizlikçi","new.terminalOnly":"Verilecek kimsesi olmayan komutlar terminalden çalışır.","update.signedOut":"Bu sayfanın oturumu kapandı. Yeniden açmak için /multi-agent:office-on çalıştır.","cleanup.failed":"{n} öğe silinemedi:","job.doctor":"Sağlık kontrolü","job.route-status":"Model yönlendirme durumu","job.scan":"Skill güvenlik taraması","job.scenario-audit":"Senaryo denetimi","job.review-analysis":"Analiz dokümanı incelemesi","jobHint.doctor":"Kurulumu ve eriştiği servisleri kontrol eder; hiçbir şeyi değiştirmez.","jobHint.route-status":"Model yönlendirmesinin nerede açık olduğunu ve son çağrıların nereye gittiğini raporlar.","jobHint.scan":"Kurulu skill'leri güvensiz kalıplar için tarar; salt okuma.","jobHint.scenario-audit":"Bir senaryo dosyasını koda karşı denetler: hangi senaryolar karşılanıyor.","jobHint.review-analysis":"Bir Jira issue'sunun analiz dokümanını inceler; hiçbir şey gönderilmez.","hud.costOffline":"Maliyet: bağlı değil","hud.autopilotOffline":"Otopilot: bağlı değil","cleanup.promptsNote":"Talimat dosyalarını kısaltma terminal komutu olarak kalır: /multi-agent:prune-prompts.","prune.title":"Eski koşu logları","prune.intro":"Seçtiğin süreden eski görev log klasörleri. Denetim kaydı, metrikler ve sayaçlar hep kalır; devam ettirilebilecek koşulara ve son dakikalarda yazılan klasörlere dokunulmaz.","prune.age":"Şundan eski","prune.days":"{n} gün","prune.scan":"Ne silineceğini gör","prune.found":"{n} görev log klasörü, yaklaşık {mb} MB","prune.more":"ve {n} tane daha","prune.safe":"Sen onaylamadan hiçbir şey silinmez.","prune.done":"{n} görev log klasörü silindi, yaklaşık {mb} MB açıldı.","station.keys":"Anahtar dolabı","stationHint.keys":"Hangi kimlik bilgileri var ve çalışıyor mu; değerleri asla gösterilmez","keys.intro":"Pipeline'ın erişebildiği her servis, adıyla. Değerler kimlik deposundan hiç çıkmaz.","keys.probe":"Canlı kontrol et","keys.unavailable":"Kimlik envanteri bu makinede çalışamadı.","keys.unmapped":"{n} servis kurulmamış; /multi-agent:setup ekler.","keys.renew":"Yenilemek ya da eklemek için terminalde çalıştır:","keys.state.present":"var","keys.state.mapped-but-missing":"depoda yok","keys.state.unmapped":"kurulmamış","keys.reach.not-probed":"kontrol edilmedi","keys.reach.reachable":"çalışıyor","keys.reach.auth-rejected":"reddedildi, yenile","keys.reach.unreachable":"erişilemiyor (VPN?)","keys.reach.no-host-configured":"sunucu adresi tanımlı değil","keys.reach.well-formed":"biçimi doğru","keys.reach.not-probeable":"kontrol edilemiyor","keys.reach.malformed":"bozuk, yenile","keys.reach.no-credential":"kayıtlı değer yok","keys.reach.probe-error":"kontrol başarısız oldu","keys.reach.server-error":"sunucu hata döndü","keys.reach.tier-1-ready":"çalışıyor","keys.reach.tier-2-ready":"çalışıyor (yedek yol)","keys.reach.tier-1-no-grant":"çalışıyor, yetki gerekiyor","keys.reach.unknown":"bilinmeyen cevap","station.memory":"Hafıza","stationHint.memory":"Pipeline'ın repo başına öğrendikleri","memory.intro":"Repo başına: kod grafı, kalıcı öğrenimler, geçmiş review bulguları ve öğrenme döngüsünün tuttuğu oturum notları.","memory.none":"Henüz hiçbir reponun hafıza rafı yok.","memory.graphAge":"graf {n} günlük","memory.noGraph":"kod grafı yok","memory.counts":"{l} öğrenim · {f} geçmiş bulgu · {s} oturum notu","memory.emptyShelf":"Burada bir şey birikmiyor: bu repodaki koşular rapor fazına varmamış.","station.system":"Sistem","stationHint.system":"CPU, bellek, disk ve pipeline'ın kullandıkları","system.cpu":"CPU","system.load":"{c} çekirdekte yük {l}","system.memory":"Bellek","system.disk":"Boş disk","system.diskOf":"toplam {v}","system.pipeline":"Pipeline","system.sessions":"{n} oturum · {k} toolkit","system.rss":"{v} bellek · loglar {l} MB","system.warn.disk-low":"Diskin %10'undan azı boş: temizlikçi eski log ve worktree'leri silebilir.","system.warn.cpu-busy":"CPU dolu: paralel koşular yavaşlar.","room.orientation":"Oryantasyon","role.trainer":"Eğitmen","station.guide":"Rehber","stationHint.guide":"Ofis nasıl çalışır: odalar, bir işin akışı, burada neler yapılır, neler terminalde kalır","station.building":"Bina","stationHint.building":"Bina rehberi: her oda, içindeki kişiler ve şu an ne yaptıkları","guide.intro":"Bu kattaki her oda pipeline'ın bir parçası. Kullanmak için odanın penceresine, iş vermek için bir kişiye tıkla.","guide.show":"Göster","guide.h.plan":"Kat planı","guide.h.flow":"Bir iş nasıl yürür","guide.h.give":"İş verme","guide.h.where":"Ofis mi, terminal mi","guide.h.security":"Güvenlik","guide.h.legend":"İşaretler","guide.room.lobby":"Jira ya da GitHub issue'sundan veya serbest metinden geliştirme koşusu ya da analiz başlatılır.","guide.room.orientation":"Bu oda: okuduğun rehber.","guide.room.office":"Ajanlar, bir koşu rollerini çağırana kadar masalarında bekler. Tek kişilik işler burada yapılır.","guide.room.kitchen":"Tek bir adım için çağrılan ajan burada biraz dinlenir, sonra masasına döner; koşunun ekibi masada kalır.","guide.room.accounting":"Koşu, repo, model ve faza göre token ve tahmini maliyet.","guide.room.restroom":"Temizlik: geçici dosyalar, biten worktree'ler, eski ref'ler, yarım kalan koşular ve eski koşu logları. Hiçbir şey silinmeden önce listesi gösterilir.","guide.room.manager":"Otopilot ve açma kapama düğmesi, kaydettiğin rutinler ve ayarlar: çıktı dili, Fable basamağı, model yönlendirmesi.","guide.room.lab":"Test işleri: bir repo için yazılan ve kontrol edilen testler.","guide.room.library":"Pipeline'ın bildikleri: repo başına stack'ler, tüm komutlar ve repo başına öğrendikleri.","guide.room.archive":"Geçmiş: biten koşular, logları ve postmortem'ler.","guide.room.mail":"Seni bekleyen ya da senin açtığın PR'lar: tüm GitHub hesapları ve Bitbucket.","guide.room.server":"Dış hatlar: toolkit MCP araçları, bağlı servisler, anahtar dolabı ve makinenin kaynakları.","guide.room.meeting":"Her repo için bir kat: /multi-agent için Geliştirme odası, /multi-agent:analysis için Analiz odası.","guide.flow.1":"Ajanlar açık ofiste masalarında bekler.","guide.flow.2":"Bir koşu bir role ihtiyaç duyunca o kişi, koşunun repo katındaki odasına yürür. Birden fazla repoya dokunan koşu, diğer repoların katında şube masası açar.","guide.flow.3":"Masa tabelasında faz, görevler bittikçe dolan çubuk ve sürmekte olan görev görünür. Bu liste terminaldeki görev widget'ıyla aynıdır.","guide.flow.4":"Tek bir adım için çağrılan ajan işi bitince mutfakta dinlenir, sonra masasına döner; ekip koşu bitene kadar masada oturur.","guide.flow.5":"Biten koşu sonucuyla birlikte iki dakika katta kalır, sonra ekip dağılır.","guide.pipeline.dev":"Geliştirme (/multi-agent): {v}","guide.pipeline.analysis":"Analiz (/multi-agent:analysis): {v}","guide.pipeline.mcp":"Toolkit MCP'yi doğrudan kullanan oturumun kendi masası olur. Bir araç çalışırken ajanı sunucu raflarına yürür.","guide.give.1":"Bir kişiye tıkla, aldığı işleri gör. Birini seç, formu doldur, onayla.","guide.give.2":"Ekip işi repo katındaki bir odada, tek kişilik iş bir masada yürür. Bir repoda aynı anda tek ekip koşusu olur.","guide.give.3":"Bir koşu sana soru sorunca masasının üstünde ve üst çubukta ! işareti çıkar.","guide.where.1":"İşler: model işi yapar ve rapor verir (review, analiz, test planı).","guide.where.2":"Pencereler: burada okuduğun bilgiler ve önce önizleme gösterip yalnızca onayınla çalışan işlemler (otopilot, stack, rutinler, temizlik, ayarlar).","guide.where.3":"Yalnızca terminal: etkileşimli ya da kurulumu değiştiren işler (setup, update, sync, uninstall). Komutlar penceresi her birinin sebebini yazar.","guide.security.1":"Sunucu yalnızca 127.0.0.1'de dinler ve /multi-agent:office-off ile durdurulana kadar çalışır.","guide.security.2":"Erişim token'ı bu sayfanın belleğinde durur. URL'ye, çereze ya da tarayıcı deposuna yazılmaz.","guide.security.3":"Makineyi değiştiren ya da iş başlatan işlemler önce önizleme gösterir, yalnızca onayınla çalışır. Her yazma kayda geçer.","guide.security.4":"Hiçbir kimlik bilgisi bu sayfaya gelmez. Anahtar dolabı yalnızca ad ve durum gösterir, yenileme terminalde /multi-agent:setup ile yapılır.","guide.security.5":"Review işleri sonucu burada raporlar, hiçbir yere yorum göndermez. Demo uydurma bir günü oynatır, hiçbir şeyi değiştirmez.","guide.legend.done":"Faz bitti","guide.legend.now":"Faz sürüyor; görevleri bittikçe dolar","guide.legend.pending":"Faz başlamadı","guide.legend.you":"Bir koşu seni bekliyor","guide.legend.ask":"Bir ajan soru sordu","guide.legend.spawn":"Bir ajan başlıyor","guide.legend.cloud":"Çalışan birinin üstündeki bulut ne yaptığını söyler; detay için tıkla.","role.developer":"Geliştirici","role.plan-critic":"Plan Eleştirmeni","role.dev-critic":"Geliştirme Eleştirmeni","role.committer":"Commit Sorumlusu","role.reporter":"Raportör","chat.askedInTerminal":"Bu oturum terminalinde sana soru soruyor. Cevabı orada ver; panel yalnızca koşunun panele bıraktığı soruları cevaplar.","table.freeText":"Serbest metin","table.prOpened":"PR #{n} açıldı","table.waitingFor.local-test":"Seni bekliyor: lokalde test edilsin mi?","table.waitingFor.user-channels-choice":"Seni bekliyor: rapor nereye gitsin","table.waitingFor.maturity":"Seni bekliyor: madde hazır değil","table.waitingFor.attended-reply":"Cevabını bekliyor","table.waitingFor.question":"Cevabını burada bekliyor","table.waitingFor.terminal":"Terminalde sana soruyor","event.guide":"Yeni misin? Rehber resepsiyonun yanındaki oryantasyon odasında.","table.crewDone":"{phase} işini bitirdi","table.headWaiting":"cevabını bekliyor","table.headQuiet":"oturumunda son zamanlarda hareket yok","table.crewNext":"{phase} sırasını bekliyor","run.report":"Rapor","run.channel.pr":"PR açıklaması","run.channel.jira":"Jira","run.channel.confluence":"Confluence","run.channel.wiki":"Wiki","run.channel.issue":"GitHub issue","run.channelState.posted":"gönderildi","run.channelState.skipped":"atlandı","run.channelState.failed":"başarısız","memory.buildGraph":"Kod grafını oluştur","memory.refreshGraph":"Kod grafını yenile","station.settings":"Ayarlar","stationHint.settings":"Çıktı dili, Fable basamağı ve model yönlendirmesi","settings.intro":"Her düğme, önizlemeden sonra ilgili terminal komutunun yaptığını yapar.","settings.language":"Çıktı dili","settings.languageHint":"Pipeline'ın sana yazdığı dil: raporlar, PR ve Jira yorumları, bu ofis.","settings.model":"Fable basamağı","settings.modelHint":"Koşular model merdiveninin tepesinde Fable kullanabilir mi (/multi-agent:model).","settings.route":"Model yönlendirmesi","settings.routeHint":"Çağrılar kayıtlı kurallara göre yönlendirilsin mi (/multi-agent:route-on ve route-off).","settings.value.language.en":"English","settings.value.language.tr":"Türkçe","settings.value.model.on":"Açık","settings.value.model.off":"Kapalı","settings.value.route.on":"Açık","settings.value.route.off":"Kapalı","settings.change":"{from} → {to}","settings.languageNote":"CLI seçicisindeki komut açıklamaları bir sonraki oturumda değişir; bu sayfayı yeni dilde görmek için /multi-agent:office-on komutunu yeniden çalıştır.","settings.terminalNote":"Yönlendirme kuralları, ücretsiz sağlayıcılar ve prompt dili terminalde kalır.","settings.freeChain":"Bu, daha önce kaydettiğin ücretsiz sağlayıcı zincirini de geri açar.","settings.freeChainTraining":"Bu, daha önce kaydettiğin ücretsiz sağlayıcı zincirini de geri açar; bu zincirde gönderilenle model eğitebilen sağlayıcılar da var."}};
@@ -1760,6 +1760,7 @@ function createWorld(opts) {
1760
1760
  let selected = null;
1761
1761
  let flash = null;
1762
1762
  let running = false;
1763
+ let rafId = 0;
1763
1764
  let lastFrame = 0;
1764
1765
  let hitList = [];
1765
1766
 
@@ -3857,7 +3858,7 @@ function createWorld(opts) {
3857
3858
  drawFlash(now);
3858
3859
  drawOverlay(now);
3859
3860
  }
3860
- requestAnimationFrame(frame);
3861
+ rafId = requestAnimationFrame(frame);
3861
3862
  }
3862
3863
 
3863
3864
  // The room a guide's "show" button pointed at blinks its outline for a moment.
@@ -4102,10 +4103,12 @@ function createWorld(opts) {
4102
4103
  if (running) return;
4103
4104
  running = true;
4104
4105
  lastFrame = 0;
4105
- requestAnimationFrame(frame);
4106
+ rafId = requestAnimationFrame(frame);
4106
4107
  },
4107
4108
  stop() {
4108
4109
  running = false;
4110
+ cancelAnimationFrame(rafId);
4111
+ rafId = 0;
4109
4112
  },
4110
4113
  };
4111
4114
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "toolkitVersion": "3.27.0"
2
+ "toolkitVersion": "3.27.1"
3
3
  }
@@ -4,7 +4,7 @@ Skill set lives in the marketplace plugins - `ai-ios-toolkit` (iOS/SwiftUI) an
4
4
 
5
5
  ### MUST: Figma access - 3-tier fallback chain (BLOCKING, pipeline-wide)
6
6
 
7
- When any task references a Figma frame (URL, node ID, or free-text "from the design"), the pipeline MUST resolve a Figma ground-truth artefact via the chain below before any UI line is written, every phase that consumes or verifies the reference (Phase 0 intake, Phase 1 plan, Phase 2 dev, Phase 3 review, Phase 4 commit, Phase 5 report). Skipping the chain has cost multiple rebuild rounds across projects.
7
+ When any task references a Figma frame (URL, node ID, or free-text "from the design"), the pipeline MUST resolve a Figma ground-truth artefact via the chain below before any UI line is written, every phase that consumes or verifies the reference (Phase 0 intake, Phase 1 plan, Phase 2 dev, Phase 3 review, Phase 4 commit, Phase 5 report).
8
8
 
9
9
  The three tiers run in strict priority order. A tier is "available" when its required credentials / inputs are present AND a probe call succeeds. Lower tiers are tried only when the higher tier is unreachable.
10
10
 
@@ -68,20 +68,23 @@ Architecture notes must cite the exact node IDs (Tier 1 or Tier 2) or attach the
68
68
 
69
69
  ## MUST: No MCP outside analysis phase (BLOCKING, pipeline-wide)
70
70
 
71
- The 3-tier fallback chain above governs Figma access in `/multi-agent:analysis` only. Once the analysis document is rendered (Phase 1 of the analysis subcommand), the analysis doc + repo Code Connect mappings (`*.figma.swift` / `*.figma.kt`) are the sole design source for every downstream phase. Calling `mcp__claude_ai_Figma__*` tools, hitting `api.figma.com`, or fetching a `figma.com/design/...` URL during Phase 2, 3, 4, 5, 6, or 7 is a violation.
71
+ The chain above runs in `/multi-agent:analysis` and Phase 1's analysis half. After that the analysis doc + Code Connect mappings (`*.figma.swift` / `*.figma.kt`) are the only design source: any Figma MCP call, `api.figma.com` request or `figma.com/design/...` fetch later is a violation.
72
72
 
73
73
  ### Phase access matrix
74
74
 
75
75
  | Phase | Sub-command examples | Figma MCP allowed | Figma REST allowed | Reason |
76
76
  |---|---|---|---|---|
77
77
  | Analysis Phase 1 | `/multi-agent:analysis` Phase 1 fetch | yes | yes (Tier 2 fallback) | Single source of design ground truth |
78
- | Plan (Phase 1) | `/multi-agent`, `/multi-agent:autopilot` | no | no | Plan reads analysis doc Section 14 + Section 6 |
78
+ | Phase 0 Step 0.5, Phase 1 Step 1.4 | full modes | yes | yes | Tier probe, then `state.evidence.figma[]` |
79
+ | Phase 1, planning half | `/multi-agent`, `/multi-agent:autopilot` | no | no | Plan reads analysis doc Section 14 + Section 6 |
79
80
  | Dev (Phase 2) | `/multi-agent`, `/multi-agent:autopilot` | no | no | Reads analysis doc + Code Connect mapping |
80
81
  | Review (Phase 3) | `/multi-agent:review`, every full-pipeline mode | no | no | Reviewer cites analysis doc Section 21 References |
81
82
  | Test (inside Phase 3) | `/multi-agent:test`, `/multi-agent:manual-test`, every full mode | no | no | Variant list comes from analysis Section 13.6 + 15.2 |
82
83
  | Commit (Phase 4) | every mode | no | no | PR body links to analysis doc URL, no design fetch |
83
84
  | Report (Phase 5) | `/multi-agent:channels`, every full mode | no | no | Channels embed analysis doc, no design fetch |
84
85
 
86
+ `run-scope-guard.mjs` blocks Figma after Phase 1; Phase 1's checkpoint holds the planning-half row.
87
+
85
88
  ### Halt condition
86
89
 
87
90
  If Phase 2+ encounters a need to look at the design (missing variant, ambiguous padding, unknown copy), the run halts and the user is instructed to re-run `/multi-agent:analysis` to regenerate the doc with the missing piece. Never silently call MCP as a fallback.
@@ -2085,7 +2085,7 @@
2085
2085
  "autopilotSafetyGate": {
2086
2086
  "type": "boolean",
2087
2087
  "default": true,
2088
- "description": "v7.0.0+ - Phase 1 autopilot safety classifier. Before autopilot mode consumes the user's approval skip, run `classify-plan-safety.mjs` over the approved plan. If the heuristic score ≥ 50 (e.g. >15 files touched, or security-path touch, or delete-without-test, or schema migration) inject a ONE-TIME pause asking for explicit manual approval - even in autopilot. Default ON because the risk of skipping this gate is asymmetric: a pause on a high-blast-radius plan costs seconds; a silent auto-merge of a bad one costs hours of rollback. Flip to `false` only for tightly-scoped autopilot workflows (e.g. batch figma component iteration) where the task class is known-safe."
2088
+ "description": "v7.0.0+ - Phase 1 autopilot safety classifier. Before autopilot mode consumes the user's approval skip, run `classify-plan-safety.mjs` over the approved plan. If it recommends a pause (one signal of weight 30+, two of weight 20+, or a score of 50; the rule table is in the script header) inject a ONE-TIME pause asking for explicit manual approval - even in autopilot. Default ON because the risk of skipping this gate is asymmetric: a pause on a high-blast-radius plan costs seconds; a silent auto-merge of a bad one costs hours of rollback. Flip to `false` only for tightly-scoped autopilot workflows (e.g. batch figma component iteration) where the task class is known-safe."
2089
2089
  },
2090
2090
  "dynamicSkillLoading": {
2091
2091
  "type": "boolean",
@@ -37,13 +37,20 @@ const NEAR_DUP = 0.9;
37
37
  const ORDER_OVERLAP = 0.5;
38
38
  const NEGATIONS = /\b(not|never|no|none|without|except|only|avoid|don't|do not)\b/gi;
39
39
 
40
+ /** The preferences, `{}` when there are none, `null` when they exist but cannot be read. */
40
41
  function prefs(env) {
41
42
  const p =
42
43
  env.MULTI_AGENT_PREFS || join(env.HOME || homedir(), ".claude", "multi-agent-preferences.json");
44
+ let text;
43
45
  try {
44
- return JSON.parse(readFileSync(p, "utf8"));
46
+ text = readFileSync(p, "utf8");
47
+ } catch (err) {
48
+ return err?.code === "ENOENT" ? {} : null;
49
+ }
50
+ try {
51
+ return JSON.parse(text);
45
52
  } catch {
46
- return {};
53
+ return null;
47
54
  }
48
55
  }
49
56
 
@@ -69,13 +76,28 @@ export function checkedSlug(slug) {
69
76
  return s.normalize("NFC");
70
77
  }
71
78
 
72
- /** True when the repo's memory must not be written. */
79
+ /**
80
+ * True when the repo's memory must not be written. Preferences that exist but
81
+ * cannot be read exclude every repo: the exclusion list they hold is unknown.
82
+ */
73
83
  export function memoryExcluded(slug, env = process.env) {
74
- const list = prefs(env)?.global?.memory?.excludeProjects;
84
+ const settings = prefs(env);
85
+ if (settings === null) {
86
+ if (!warnedUnreadablePrefs) {
87
+ warnedUnreadablePrefs = true;
88
+ process.stderr.write(
89
+ "memory: multi-agent-preferences.json cannot be read, so no repository's memory is written until it parses again\n",
90
+ );
91
+ }
92
+ return true;
93
+ }
94
+ const list = settings?.global?.memory?.excludeProjects;
75
95
  const want = String(slug ?? "").normalize("NFC");
76
- return Array.isArray(list) && list.some((p) => String(p).normalize("NFC") === want);
96
+ return Array.isArray(list) && list.some((entry) => String(entry).normalize("NFC") === want);
77
97
  }
78
98
 
99
+ let warnedUnreadablePrefs = false;
100
+
79
101
  /**
80
102
  * @param {Array<{ts: string, outcome: string}>} feedback rows for one entry
81
103
  * @returns {{useful: number, deadEnd: number, corrected: number, suppressed: boolean, corroborated: boolean, strength: number}}
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # checkpoint-fold.sh - fold a run's checkpoint commits back into the working
4
+ # tree before the real commit.
5
+ #
6
+ # A run commits as it goes so a crash loses nothing: Phase 2 writes
7
+ # `wip(<scope>): <summary> [<task>]` after each plan task, and the user test
8
+ # writes `WIP: <task> - changes for user test`. None of them belongs in the
9
+ # PR. This counts those commits from HEAD down, following first parents, and
10
+ # stops at the first commit that is neither, so a commit someone else made on
11
+ # the branch is never touched. The count is bounded by origin/<base> when that
12
+ # ref exists. A mixed reset then leaves the changes unstaged for the caller to
13
+ # stage file by file.
14
+ #
15
+ # Usage:
16
+ # checkpoint-fold.sh --repo <dir> --task <id> [--base <branch>] [--dry-run]
17
+ #
18
+ # Prints {"folded": N}. Exit codes: 0 done (N may be 0), 1 usage error,
19
+ # 6 the fold would pass the first commit of the history, or the reset failed.
20
+ set -uo pipefail
21
+
22
+ usage() {
23
+ echo "usage: checkpoint-fold.sh --repo <dir> --task <id> [--base <branch>] [--dry-run]" >&2
24
+ exit 1
25
+ }
26
+
27
+ REPO="" TASK="" BASE="" DRY=0
28
+ while [ $# -gt 0 ]; do
29
+ case "$1" in
30
+ --dry-run) DRY=1; shift; continue ;;
31
+ esac
32
+ [ $# -ge 2 ] || usage
33
+ case "$1" in
34
+ --repo) REPO="$2" ;;
35
+ --task) TASK="$2" ;;
36
+ --base) BASE="$2" ;;
37
+ *) echo "checkpoint-fold: unknown argument $1" >&2; usage ;;
38
+ esac
39
+ shift 2
40
+ done
41
+ [ -n "$REPO" ] && [ -n "$TASK" ] || usage
42
+ git -C "$REPO" rev-parse --git-dir >/dev/null 2>&1 || { echo "checkpoint-fold: --repo is not a git repository" >&2; exit 1; }
43
+
44
+ RANGE=HEAD
45
+ if [ -n "$BASE" ] && git -C "$REPO" rev-parse -q --verify "origin/$BASE" >/dev/null; then
46
+ RANGE="origin/$BASE..HEAD"
47
+ fi
48
+
49
+ N="$(git -C "$REPO" log --first-parent --format=%s "$RANGE" 2>/dev/null | awk -v id="$TASK" '
50
+ $0 == "WIP: " id || index($0, "WIP: " id " ") == 1 || ($0 ~ /^wip\(/ && index($0, "[" id "]")) { n++; next }
51
+ { exit }
52
+ END { print n + 0 }')"
53
+
54
+ if [ "$N" -gt 0 ] && [ "$DRY" = 0 ]; then
55
+ git -C "$REPO" rev-parse -q --verify "HEAD~$N" >/dev/null ||
56
+ { echo "checkpoint-fold: every commit down to the root is a checkpoint; fold by hand" >&2; exit 6; }
57
+ git -C "$REPO" reset -q "HEAD~$N" || exit 6
58
+ fi
59
+ printf '{"folded":%s}\n' "$N"
@@ -239,7 +239,7 @@ export class LedgerError extends Error {
239
239
  * Yes when its tree is the index's, or the tree `git add -A` would stage from
240
240
  * the working tree (built in a throwaway copy of the index, so the real index
241
241
  * is untouched). The hook runs before a `git add ... && git commit` line
242
- * stages anything, and Phase 4's `git reset HEAD~1` leaves a checkpoint
242
+ * stages anything, and Phase 4's checkpoint fold (`git reset HEAD~N`) leaves a checkpoint
243
243
  * commit's new files untracked; both still match the evidence they were
244
244
  * tested with, while a file added after the evidence does not. Each sha is
245
245
  * asked once; anything git cannot answer is "no".
@@ -45,6 +45,7 @@ import { spawn, spawnSync } from "node:child_process";
45
45
  import { createHash, randomBytes } from "node:crypto";
46
46
  import {
47
47
  chmodSync,
48
+ closeSync,
48
49
  existsSync,
49
50
  mkdirSync,
50
51
  openSync,
@@ -67,6 +68,7 @@ const HERE = dirname(fileURLToPath(import.meta.url));
67
68
  // only, and every office-on that starts one mints a new token.
68
69
  const IDLE_MINUTES = 0;
69
70
  const MAX_HOURS = 0;
71
+ const READY_MS = 15000;
70
72
  /** How far a process's start may sit before its token file's startedAt. */
71
73
  const START_SKEW_MS = 120 * 1000;
72
74
 
@@ -353,21 +355,45 @@ export async function officeOn({ env = process.env, open = true } = {}) {
353
355
  },
354
356
  );
355
357
  child.unref();
356
- const info = await waitForReady(ready, 15000);
357
- rmSync(ready, { force: true });
358
- if (!info) throw new Error("the server did not report ready");
359
- writeState(env, {
360
- pid: info.pid,
361
- port: info.port,
362
- url: info.url,
363
- tokenFile: info.tokenFile,
364
- idleMinutes: info.idleMinutes,
365
- maxHours: info.maxHours ?? null,
366
- startedAt: new Date().toISOString(),
367
- serverDigest: digestOf(server),
368
- });
369
- s = current(env);
370
- if (!s) throw new Error("the server stopped right after it started");
358
+ const stop = () => {
359
+ try {
360
+ process.kill(-child.pid, "SIGTERM");
361
+ } catch {
362
+ try {
363
+ child.kill("SIGTERM");
364
+ } catch {
365
+ /* already gone */
366
+ }
367
+ }
368
+ };
369
+ const readyEnv = Number(env.MA_OFFICE_READY_MS);
370
+ const readyMs = Number.isInteger(readyEnv) && readyEnv > 0 ? readyEnv : READY_MS;
371
+ try {
372
+ let info;
373
+ try {
374
+ info = await waitForReady(ready, readyMs);
375
+ } finally {
376
+ closeSync(out);
377
+ rmSync(ready, { force: true });
378
+ }
379
+ if (!info) throw new Error("the server did not report ready");
380
+ writeState(env, {
381
+ pid: info.pid,
382
+ port: info.port,
383
+ url: info.url,
384
+ tokenFile: info.tokenFile,
385
+ idleMinutes: info.idleMinutes,
386
+ maxHours: info.maxHours ?? null,
387
+ startedAt: new Date().toISOString(),
388
+ serverDigest: digestOf(server),
389
+ });
390
+ s = current(env);
391
+ if (!s) throw new Error("the server stopped right after it started");
392
+ } catch (err) {
393
+ stop();
394
+ rmSync(stateFile(env), { force: true });
395
+ throw err;
396
+ }
371
397
  }
372
398
  const page = `${s.url}/office`;
373
399
  const remote = startRemoteClient(env);
@@ -13,7 +13,7 @@
13
13
  # lost, and nothing that was not asked for is paid for.
14
14
  #
15
15
  # Usage:
16
- # <command> 2>&1 | offload-ref.sh --phase 3 --label build [--tail N] [--root DIR]
16
+ # <command> 2>&1 | offload-ref.sh --phase 2 --label build [--tail N] [--root DIR]
17
17
  # offload-ref.sh --phase 4 --label diff --input path/to/file
18
18
  #
19
19
  # Flags:
@@ -7,9 +7,10 @@
7
7
  * finding still open gets one ruling, recorded, never dropped:
8
8
  *
9
9
  * escalate load-bearing: blocking severity, or a security finding
10
- * (ruleId SEC-* / CON-SEC-*, a security criteriaSource, or the
11
- * security-auditor's `security` object). The run stops and the
12
- * user decides.
10
+ * (`foundBy: "security-auditor"`, ruleId SEC-* / CON-SEC-*, a
11
+ * security criteriaSource, or a `security` object). The auditor's
12
+ * own tag is checked first because the triage schema drops the
13
+ * `security` envelope. The run stops and the user decides.
13
14
  * parked anything else. It leaves the loop as a follow-up with its
14
15
  * reason, shown before commit (Phase 4 Step 0b), carried in the
15
16
  * PR follow-ups and recorded in the debt list, so the run can finish instead of stopping on a
@@ -37,6 +38,7 @@ const SECURITY_RULE = /^(CON-)?SEC-/i;
37
38
  /** True when a finding may not leave the loop without the user. */
38
39
  export function loadBearing(f) {
39
40
  if (f?.severity === "blocking") return true;
41
+ if (f?.foundBy === "security-auditor") return true;
40
42
  if (typeof f?.ruleId === "string" && SECURITY_RULE.test(f.ruleId)) return true;
41
43
  if (f?.security && typeof f.security === "object") return true;
42
44
  return typeof f?.criteriaSource === "string" && /security/i.test(f.criteriaSource);
@@ -99,6 +99,17 @@ const LINE_COMMENT = /(\.(py|pyi|ya?ml|sh|bash|zsh|rb|toml|coffee)|(^|\/)(GNU)?[
99
99
  const TIGHT_LANGS =
100
100
  /\.(js|jsx|mjs|cjs|ts|tsx|java|go|cs|swift|kt|kts|json|rs|dart|scala|py|pyi|c|h|cc|cpp|hpp|m|mm)$/;
101
101
  const LEADING_OPERATOR_LANGS = /\.(kt|kts|swift|go|scala)$/;
102
+ // A newline ends the statement here, so joining two lines changes the program.
103
+ const NEWLINE_TERMINATED = new RegExp(
104
+ [
105
+ String.raw`\.(sh|bash|zsh|ksh|fish|rb|rake|gemspec|toml|dockerfile)$`,
106
+ String.raw`(^|\/)\.envrc$`,
107
+ String.raw`(^|\/)[^/]*Rakefile$`,
108
+ String.raw`(^|\/)(Gemfile|Podfile|Fastfile|Appfile|Matchfile|Snapfile|Scanfile|Gymfile|Deliverfile|Pluginfile|Dangerfile|Brewfile|Vagrantfile|Jenkinsfile)$`,
109
+ String.raw`(^|\/)(Dockerfile|Containerfile)([.-][^/]*)?$`,
110
+ ].join("|"),
111
+ "i",
112
+ );
102
113
  const BREAK_KEEPERS = /\b(return|throw|yield|break|continue)$/;
103
114
  const LEADING_OPERATOR = /^[+\-*/%&|^.?]/;
104
115
  const TIGHT = /\s*([(){}[\],;:])\s*/g;
@@ -135,8 +146,9 @@ function foldLine(line, hashComments) {
135
146
  /**
136
147
  * The layout-free form of some lines. Each line is folded on its own (linear
137
148
  * in the hunk), then the lines are joined by a space, except that a break
138
- * after return, throw, yield, break or continue, and in Kotlin, Swift, Go or
139
- * Scala a break before a leading operator, stays a break. Space next to
149
+ * after return, throw, yield, break or continue, in Kotlin, Swift, Go or
150
+ * Scala a break before a leading operator, and every break in shell, Ruby,
151
+ * TOML and Dockerfiles, stays a break. Space next to
140
152
  * brackets, commas, semicolons and colons is dropped only in TIGHT_LANGS, and
141
153
  * never in a hunk that holds a C preprocessor line.
142
154
  */
@@ -150,6 +162,7 @@ function outsideStrings(text, file = "") {
150
162
  return;
151
163
  }
152
164
  const keepBreak =
165
+ NEWLINE_TERMINATED.test(file) ||
153
166
  BREAK_KEEPERS.test(lines[i - 1]) ||
154
167
  (LEADING_OPERATOR_LANGS.test(file) && LEADING_OPERATOR.test(line));
155
168
  joined += (keepBreak ? "\u23ce" : " ") + line;