okstra 0.185.0 → 0.186.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/commands/chat/chat.mjs +62 -15
- package/dist/commands/chat/chat.mjs.map +1 -1
- package/docs/architecture.md +1 -1
- package/docs/cli.md +2 -2
- package/docs/for-ai/skills/okstra-chat.md +7 -1
- package/docs/project-structure-overview.md +1 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
- package/runtime/prompts/lead/plan-body-verification.md +8 -7
- package/runtime/prompts/profiles/implementation-planning.md +3 -3
- package/runtime/python/okstra_ctl/cmux.py +63 -35
- package/runtime/python/okstra_ctl/incremental_carry.py +149 -5
- package/runtime/python/okstra_ctl/incremental_scope.py +25 -3
- package/runtime/python/okstra_ctl/plan_items.py +40 -4
- package/runtime/python/okstra_ctl/report_html/common.py +86 -11
- package/runtime/python/okstra_ctl/report_html/filters.py +27 -10
- package/runtime/python/okstra_ctl/report_html/render.py +1 -0
- package/runtime/python/okstra_ctl/report_html/report_index.py +5 -1
- package/runtime/python/okstra_ctl/report_html/view_models/implementation_planning.py +1 -1
- package/runtime/skills/okstra-chat/SKILL.md +25 -13
- package/runtime/templates/reports/html/assets/base.css +48 -3
- package/runtime/templates/reports/html/base.template.html +7 -4
- package/runtime/templates/reports/html/i18n/en.json +86 -8
- package/runtime/templates/reports/html/i18n/ko.json +86 -8
- package/runtime/templates/reports/html/macros/forms.html +74 -55
- package/runtime/templates/reports/html/macros/layout.html +2 -2
- package/runtime/templates/reports/html/macros/visualizations.html +1 -1
- package/runtime/templates/reports/html/tasks/change-impact-analysis.template.html +2 -2
- package/runtime/templates/reports/html/tasks/error-analysis.template.html +3 -3
- package/runtime/templates/reports/html/tasks/feature-analysis.template.html +4 -4
- package/runtime/templates/reports/html/tasks/final-verification.template.html +3 -3
- package/runtime/templates/reports/html/tasks/implementation-option-selection.template.html +9 -9
- package/runtime/templates/reports/html/tasks/implementation-planning.template.html +20 -18
- package/runtime/templates/reports/html/tasks/implementation.template.html +3 -3
- package/runtime/templates/reports/html/tasks/improvement-discovery.template.html +3 -3
- package/runtime/templates/reports/html/tasks/project-analysis.template.html +10 -10
- package/runtime/templates/reports/html/tasks/release-handoff.template.html +2 -2
- package/runtime/templates/reports/html/tasks/requirements-discovery.template.html +4 -4
- package/runtime/validators/validate-run.py +19 -19
|
@@ -108,8 +108,11 @@ textarea, select { width: 100%; max-width: 60rem; padding: .55rem; font: inherit
|
|
|
108
108
|
.clarification-expected dt { font-weight: 600; margin-bottom: .3rem; }
|
|
109
109
|
.clarification-expected dd { margin: 0; }
|
|
110
110
|
.clarification-item label { font-weight: 600; margin-bottom: .3rem; }
|
|
111
|
-
.activity-list { display: grid; gap: .
|
|
112
|
-
.activity-card { padding:
|
|
111
|
+
.activity-list { display: grid; gap: .4rem; }
|
|
112
|
+
.activity-card { padding: .55rem .8rem; border: 1px solid color-mix(in srgb, CanvasText 14%, transparent); border-radius: 12px; }
|
|
113
|
+
.activity-card h3 { font-size: 1rem; margin: 0 0 .15rem; }
|
|
114
|
+
.clarification-item.is-closed { padding: .35rem 0; }
|
|
115
|
+
.clarification-item.is-closed summary { cursor: pointer; font-weight: 600; }
|
|
113
116
|
.activity-card > :first-child, .approval-context > :first-child { margin-top: 0; }
|
|
114
117
|
.activity-card > :last-child, .approval-context > :last-child { margin-bottom: 0; }
|
|
115
118
|
.activity-card details { margin-top: .8rem; }
|
|
@@ -122,7 +125,49 @@ button:active { transform: translateY(1px); }
|
|
|
122
125
|
button:focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }
|
|
123
126
|
button[data-action="export-user-response"] { background: Highlight; border-color: Highlight; color: HighlightText; font-weight: 600; }
|
|
124
127
|
button[data-action="export-user-response"]:hover { background: color-mix(in srgb, Highlight 82%, CanvasText); }
|
|
128
|
+
.back-to-top-wrap {
|
|
129
|
+
position: fixed;
|
|
130
|
+
right: 1.2rem;
|
|
131
|
+
bottom: 1.2rem;
|
|
132
|
+
z-index: 15;
|
|
133
|
+
display: flex;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
align-items: flex-end;
|
|
136
|
+
}
|
|
137
|
+
.back-to-top {
|
|
138
|
+
padding: .55rem .9rem;
|
|
139
|
+
border-radius: 8px;
|
|
140
|
+
border: 1px solid color-mix(in srgb, CanvasText 28%, transparent);
|
|
141
|
+
background: color-mix(in srgb, Canvas 92%, CanvasText 8%);
|
|
142
|
+
color: CanvasText;
|
|
143
|
+
text-decoration: none;
|
|
144
|
+
font: inherit;
|
|
145
|
+
font-size: .9rem;
|
|
146
|
+
box-shadow: 0 2px 8px color-mix(in srgb, CanvasText 18%, transparent);
|
|
147
|
+
}
|
|
148
|
+
.back-to-top:hover { background: color-mix(in srgb, CanvasText 12%, Canvas); }
|
|
149
|
+
.back-to-top:focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }
|
|
150
|
+
.back-to-top-index {
|
|
151
|
+
display: none;
|
|
152
|
+
box-sizing: border-box;
|
|
153
|
+
width: min(22rem, calc(100vw - 2.4rem));
|
|
154
|
+
max-height: min(70vh, 32rem);
|
|
155
|
+
overflow: auto;
|
|
156
|
+
margin: 0 0 .4rem;
|
|
157
|
+
padding: .8rem 1rem;
|
|
158
|
+
border-radius: 12px;
|
|
159
|
+
border: 1px solid color-mix(in srgb, CanvasText 14%, transparent);
|
|
160
|
+
background: Canvas;
|
|
161
|
+
box-shadow: 0 8px 24px color-mix(in srgb, CanvasText 22%, transparent);
|
|
162
|
+
}
|
|
163
|
+
.back-to-top-index ol { margin: 0; padding-left: 1.2rem; }
|
|
164
|
+
.back-to-top-index li { margin: .25em 0; }
|
|
165
|
+
.back-to-top-index a { color: inherit; }
|
|
166
|
+
@media (hover: hover) {
|
|
167
|
+
.back-to-top-wrap:hover .back-to-top-index,
|
|
168
|
+
.back-to-top-wrap:focus-within .back-to-top-index { display: block; }
|
|
169
|
+
}
|
|
125
170
|
/* A seven-column table needs 42em of floor, more than a phone can give. */
|
|
126
171
|
@media (max-width: 640px) { section { padding: 1rem; } .visualization { display: none; } th, td { min-width: 4.5em; } nav.report-index ol { columns: 1; } }
|
|
127
|
-
@media print { .skip-link, script { display: none !important; } body { color: #000; background: #fff; } section { break-inside: avoid; border-color: #bbb; } .visualization-fallback { display: table; } }
|
|
172
|
+
@media print { .skip-link, .back-to-top-wrap, script { display: none !important; } body { color: #000; background: #fff; } section { break-inside: avoid; border-color: #bbb; } .visualization-fallback { display: table; } }
|
|
128
173
|
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; padding: .1em .3em; border-radius: 4px; background: color-mix(in srgb, CanvasText 8%, Canvas); }
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
{% from "html/macros/forms.html" import clarification_responses %}
|
|
3
3
|
{% from "html/macros/layout.html" import row_key %}
|
|
4
|
-
<html lang="
|
|
4
|
+
<html lang="{{ lang }}" data-task-template="{{ taskType }}">
|
|
5
5
|
<head>
|
|
6
6
|
<meta charset="utf-8">
|
|
7
7
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
8
8
|
<title>{{ (runMeta.task_key.split(':') | last)[:16] }} · {{ taskType }} #{{ runMeta.seq }}</title>
|
|
9
9
|
<style>{{ css | safe }}</style>
|
|
10
10
|
</head>
|
|
11
|
-
<body>
|
|
11
|
+
<body id="top">
|
|
12
12
|
<a class="skip-link" href="#main-content">{{ t('base.skip-to-report-content') }}</a>
|
|
13
13
|
<header class="human-report-header">
|
|
14
14
|
<p class="eyebrow">{{ taskType }}</p>
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
{% if reportMeta.elapsed %}<div><dt>{{ t('base.elapsed') }}</dt><dd data-report-meta="elapsed">{{ reportMeta.elapsed }}</dd></div>{% endif %}
|
|
21
21
|
</dl>
|
|
22
22
|
<p class="lede">{{ humanSummary.headline | inline_code }}</p>
|
|
23
|
-
<p>{{ humanSummary.outcome | inline_code }}</p>
|
|
24
23
|
{% if executionRoles %}
|
|
25
24
|
<section data-report-section="execution-roles">
|
|
26
25
|
<h2>{{ t('base.execution-roles') }}</h2>
|
|
@@ -52,7 +51,7 @@
|
|
|
52
51
|
<ol class="ledger">
|
|
53
52
|
{% for row_id, row in evidenceIndex.items() %}
|
|
54
53
|
<li class="ledger-item" id="id-{{ row_id }}">
|
|
55
|
-
<p class="ledger-key"><span class="ledger-id">{{ row_id }}</span><span class="ledger-kind">{{ row.kind | enum_label('ledgerKind') }}</span></p>
|
|
54
|
+
<p class="ledger-key"><span class="ledger-id">{{ row_id | inline_code }}</span><span class="ledger-kind">{{ row.kind | enum_label('ledgerKind') }}</span></p>
|
|
56
55
|
<p class="ledger-text">{{ row.text | inline_code }}</p>
|
|
57
56
|
{% if row.codeEvidence %}<p class="ledger-source"><span>{{ t('base.source') }}</span> {{ row.codeEvidence | code_evidence }}</p>
|
|
58
57
|
{% elif row.source %}<p class="ledger-source"><span>{{ t('base.source') }}</span> {{ row.source | inline_code }}</p>{% endif %}
|
|
@@ -115,6 +114,10 @@
|
|
|
115
114
|
<p class="user-response-hint">{{ t('base.export-downloads') }} <code>user-response-{{ runMeta.task_type }}-{{ runMeta.seq }}.md</code>{{ t('base.drop-that-file-into') }} <code>runs/{{ runMeta.task_type }}/user-responses/</code> {{ t('base.and-the-next-run-picks-your-answers-up-on-it') }}</p>
|
|
116
115
|
<pre id="user-response-output" aria-live="polite"></pre>
|
|
117
116
|
</footer>{% endif %}
|
|
117
|
+
<div class="back-to-top-wrap">
|
|
118
|
+
<nav class="back-to-top-index" aria-label="{{ t('base.contents') }}"><!--report-index-items--></nav>
|
|
119
|
+
<a class="back-to-top" href="#top">{{ t('base.back-to-top') }}</a>
|
|
120
|
+
</div>
|
|
118
121
|
<script id="run-meta" type="application/json">{{ {
|
|
119
122
|
"task-key": runMeta.task_key,
|
|
120
123
|
"task-type": runMeta.task_type,
|
|
@@ -81,7 +81,8 @@
|
|
|
81
81
|
"cross-check-consensus": "Agreed across workers",
|
|
82
82
|
"cross-check-dissent": "Workers disagreed",
|
|
83
83
|
"missing-information": "Missing information",
|
|
84
|
-
"follow-up": "Follow-up"
|
|
84
|
+
"follow-up": "Follow-up",
|
|
85
|
+
"plan-item": "Plan item"
|
|
85
86
|
}
|
|
86
87
|
},
|
|
87
88
|
"enumHint": {
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
},
|
|
95
96
|
"base": {
|
|
96
97
|
"skip-to-report-content": "Skip to report content",
|
|
98
|
+
"back-to-top": "Back to top",
|
|
97
99
|
"contents": "Contents",
|
|
98
100
|
"task": "Task",
|
|
99
101
|
"execution-roles": "Execution roles",
|
|
@@ -153,6 +155,8 @@
|
|
|
153
155
|
"answer-as": "Answer as",
|
|
154
156
|
"questions-waiting-on-you": "Questions waiting on you",
|
|
155
157
|
"count-questions-waiting-on-you": "{count} questions waiting on you",
|
|
158
|
+
"answered-questions": "Answered questions",
|
|
159
|
+
"count-answered-questions": "{count} answered questions",
|
|
156
160
|
"your-answer-to-id": "Your answer to {id}",
|
|
157
161
|
"choose-one": "Choose one",
|
|
158
162
|
"recommended": "Recommended",
|
|
@@ -165,7 +169,45 @@
|
|
|
165
169
|
"why-required-for-changes-or-rejection": "Why — required when you send it back or reject it",
|
|
166
170
|
"answer-the-blockers-then-regenerate": "Answer {ids}, export your answers, then regenerate the report with the clarification resume command.",
|
|
167
171
|
"selected-direction-invalidated": "Selected direction invalidated",
|
|
168
|
-
"return-to-option-selection": "This plan cannot be approved. Re-enter implementation option selection with:"
|
|
172
|
+
"return-to-option-selection": "This plan cannot be approved. Re-enter implementation option selection with:",
|
|
173
|
+
"select-an-implementation-direction": "Select an implementation direction",
|
|
174
|
+
"direction": "Direction",
|
|
175
|
+
"confirmed": "Confirmed",
|
|
176
|
+
"selection-note": "Selection note",
|
|
177
|
+
"constraints": "Constraints"
|
|
178
|
+
},
|
|
179
|
+
"layout": {
|
|
180
|
+
"evidence": "Evidence:",
|
|
181
|
+
"supporting-evidence": "Supporting evidence:",
|
|
182
|
+
"id": "ID",
|
|
183
|
+
"name": "Name",
|
|
184
|
+
"kind": "Kind",
|
|
185
|
+
"status": "Status",
|
|
186
|
+
"source": "Source",
|
|
187
|
+
"subject": "Subject",
|
|
188
|
+
"answer": "Answer",
|
|
189
|
+
"disposition": "Disposition",
|
|
190
|
+
"sha": "SHA",
|
|
191
|
+
"order": "Order",
|
|
192
|
+
"plan-step": "Plan step",
|
|
193
|
+
"proposed-by": "Proposed by",
|
|
194
|
+
"lens": "Lens",
|
|
195
|
+
"result": "Result",
|
|
196
|
+
"version": "Version",
|
|
197
|
+
"version-source": "Version source",
|
|
198
|
+
"symbol": "Symbol",
|
|
199
|
+
"owner": "Owner",
|
|
200
|
+
"adapter": "Adapter",
|
|
201
|
+
"direction": "Direction",
|
|
202
|
+
"area": "Area",
|
|
203
|
+
"confidence": "Confidence",
|
|
204
|
+
"impact": "Impact",
|
|
205
|
+
"effort": "Effort",
|
|
206
|
+
"risk": "Risk",
|
|
207
|
+
"checked": "checked",
|
|
208
|
+
"none": "none",
|
|
209
|
+
"coverage-percent": "Coverage",
|
|
210
|
+
"scope-precision-percent": "Scope precision"
|
|
169
211
|
},
|
|
170
212
|
"visualizations": {
|
|
171
213
|
"component": "Component",
|
|
@@ -201,7 +243,8 @@
|
|
|
201
243
|
"what-this-does-to-operations": "What this does to operations",
|
|
202
244
|
"area": "Area",
|
|
203
245
|
"impact": "Impact",
|
|
204
|
-
"there-is-no-operational-impact": "There is no operational impact."
|
|
246
|
+
"there-is-no-operational-impact": "There is no operational impact.",
|
|
247
|
+
"unsettled": "Unsettled"
|
|
205
248
|
},
|
|
206
249
|
"error-analysis": {
|
|
207
250
|
"what-you-saw": "What you saw",
|
|
@@ -217,7 +260,8 @@
|
|
|
217
260
|
"signal-that-rejects-it": "Signal that rejects it:",
|
|
218
261
|
"next-step": "Next step",
|
|
219
262
|
"recommended-task": "Recommended task",
|
|
220
|
-
"the-cause-this-rests-on": "The cause this rests on"
|
|
263
|
+
"the-cause-this-rests-on": "The cause this rests on",
|
|
264
|
+
"run": "Run"
|
|
221
265
|
},
|
|
222
266
|
"feature-analysis": {
|
|
223
267
|
"feature-overview": "Feature overview",
|
|
@@ -234,7 +278,10 @@
|
|
|
234
278
|
"nothing-was-recorded": "Nothing was recorded.",
|
|
235
279
|
"state-once-it-is-done": "State once it is done",
|
|
236
280
|
"permissions-and-flags": "Permissions and flags",
|
|
237
|
-
"non-functional-concerns": "Non-functional concerns"
|
|
281
|
+
"non-functional-concerns": "Non-functional concerns",
|
|
282
|
+
"on-failure": "On failure:",
|
|
283
|
+
"tests": "Tests:",
|
|
284
|
+
"gaps": "Gaps:"
|
|
238
285
|
},
|
|
239
286
|
"final-verification": {
|
|
240
287
|
"verification-verdict": "Verification verdict",
|
|
@@ -276,7 +323,15 @@
|
|
|
276
323
|
"candidate": "Candidate",
|
|
277
324
|
"disposition": "Disposition",
|
|
278
325
|
"reason": "Reason",
|
|
279
|
-
"no-audit-entries": "No candidate was merged or rejected."
|
|
326
|
+
"no-audit-entries": "No candidate was merged or rejected.",
|
|
327
|
+
"selection-status": "Selection status",
|
|
328
|
+
"mode": "Mode",
|
|
329
|
+
"routing": "Routing",
|
|
330
|
+
"preselected-direction": "Preselected direction",
|
|
331
|
+
"option-id": "Option ID",
|
|
332
|
+
"direction": "Direction",
|
|
333
|
+
"confirmation-evidence": "Confirmation evidence",
|
|
334
|
+
"citation": "Citation"
|
|
280
335
|
},
|
|
281
336
|
"implementation-planning": {
|
|
282
337
|
"what-the-plan-is-for": "What the plan is for",
|
|
@@ -355,7 +410,24 @@
|
|
|
355
410
|
"what-each-agent-did": "What each agent did",
|
|
356
411
|
"commands-and-evidence": "Commands and evidence",
|
|
357
412
|
"unblock-condition": "Unblock condition:",
|
|
358
|
-
"agent-evidence": "Agent evidence:"
|
|
413
|
+
"agent-evidence": "Agent evidence:",
|
|
414
|
+
"selected-direction": "Selected direction",
|
|
415
|
+
"source-report": "Source report",
|
|
416
|
+
"snapshot": "Snapshot",
|
|
417
|
+
"direction-realization": "Direction realization",
|
|
418
|
+
"core-mechanism": "Core mechanism",
|
|
419
|
+
"interfaces": "Interfaces",
|
|
420
|
+
"plan-coverage": "Plan coverage",
|
|
421
|
+
"coverage-percent": "Coverage",
|
|
422
|
+
"scope-precision-percent": "Scope precision",
|
|
423
|
+
"direction-invalidated": "Direction invalidated",
|
|
424
|
+
"code-evidence": "Code evidence",
|
|
425
|
+
"re-entry-route": "Re-entry route",
|
|
426
|
+
"original-requirement": "Original requirement",
|
|
427
|
+
"stages": "Stages",
|
|
428
|
+
"status": "Status",
|
|
429
|
+
"extract": "Extract",
|
|
430
|
+
"keep": "Keep as-is"
|
|
359
431
|
},
|
|
360
432
|
"implementation": {
|
|
361
433
|
"what-was-delivered": "What was delivered",
|
|
@@ -366,6 +438,7 @@
|
|
|
366
438
|
"implemented-by": "Implemented by",
|
|
367
439
|
"verification-result": "Verification result",
|
|
368
440
|
"independent-check": "Independent check:",
|
|
441
|
+
"exit-code": "exit code",
|
|
369
442
|
"what-is-left": "What is left",
|
|
370
443
|
"nothing-was-changed-outside-the-plan": "Nothing was changed outside the plan.",
|
|
371
444
|
"commits-delivered": "Commits delivered",
|
|
@@ -453,6 +526,7 @@
|
|
|
453
526
|
"pr-result": "PR Result:",
|
|
454
527
|
"pull-request-open": "Pull request Open",
|
|
455
528
|
"conflict-verdict": "Conflict verdict",
|
|
529
|
+
"base-branch": "Base branch:",
|
|
456
530
|
"commits-delivered": "Commits delivered",
|
|
457
531
|
"there-are-no-commits": "There are no commits.",
|
|
458
532
|
"commit": "Commit",
|
|
@@ -479,7 +553,11 @@
|
|
|
479
553
|
"next-task": "Next task:",
|
|
480
554
|
"this-requirements-task-stands-alone-nothing": "This requirements task stands alone; nothing else feeds it.",
|
|
481
555
|
"decisions-that-are-yours": "Decisions that are yours",
|
|
482
|
-
"no-further-decision-is-needed": "No further decision is needed."
|
|
556
|
+
"no-further-decision-is-needed": "No further decision is needed.",
|
|
557
|
+
"settled": "Settled",
|
|
558
|
+
"decision-needed": "Decision needed",
|
|
559
|
+
"glossary": "Glossary",
|
|
560
|
+
"decision-record": "Decision record"
|
|
483
561
|
}
|
|
484
562
|
}
|
|
485
563
|
}
|
|
@@ -81,7 +81,8 @@
|
|
|
81
81
|
"cross-check-consensus": "작업자 간 합의",
|
|
82
82
|
"cross-check-dissent": "작업자 간 이견",
|
|
83
83
|
"missing-information": "빠진 정보",
|
|
84
|
-
"follow-up": "후속 작업"
|
|
84
|
+
"follow-up": "후속 작업",
|
|
85
|
+
"plan-item": "계획 항목"
|
|
85
86
|
}
|
|
86
87
|
},
|
|
87
88
|
"enumHint": {
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
},
|
|
95
96
|
"base": {
|
|
96
97
|
"skip-to-report-content": "리포트 본문으로 건너뛰기",
|
|
98
|
+
"back-to-top": "맨 위로",
|
|
97
99
|
"contents": "목차",
|
|
98
100
|
"task": "태스크",
|
|
99
101
|
"execution-roles": "실행 역할",
|
|
@@ -153,6 +155,8 @@
|
|
|
153
155
|
"answer-as": "답변 형식",
|
|
154
156
|
"questions-waiting-on-you": "답변을 기다리는 질문",
|
|
155
157
|
"count-questions-waiting-on-you": "답변을 기다리는 질문 {count}건",
|
|
158
|
+
"answered-questions": "답한 질문",
|
|
159
|
+
"count-answered-questions": "답한 질문 {count}건",
|
|
156
160
|
"your-answer-to-id": "{id}에 대한 답변",
|
|
157
161
|
"choose-one": "하나를 선택하세요",
|
|
158
162
|
"recommended": "권장",
|
|
@@ -165,7 +169,45 @@
|
|
|
165
169
|
"why-required-for-changes-or-rejection": "사유 — 반려하거나 다시 고치게 할 때는 반드시 적어야 합니다",
|
|
166
170
|
"answer-the-blockers-then-regenerate": "{ids}에 답한 뒤 답변을 내보내고, clarification resume 명령으로 리포트를 다시 만드세요.",
|
|
167
171
|
"selected-direction-invalidated": "선택 방향 무효화",
|
|
168
|
-
"return-to-option-selection": "이 계획은 승인할 수 없습니다. 다음 명령으로 구현 방향 선택 단계에 다시 진입하세요:"
|
|
172
|
+
"return-to-option-selection": "이 계획은 승인할 수 없습니다. 다음 명령으로 구현 방향 선택 단계에 다시 진입하세요:",
|
|
173
|
+
"select-an-implementation-direction": "구현 방향을 선택하세요",
|
|
174
|
+
"direction": "방향",
|
|
175
|
+
"confirmed": "확인함",
|
|
176
|
+
"selection-note": "선택 메모",
|
|
177
|
+
"constraints": "제약"
|
|
178
|
+
},
|
|
179
|
+
"layout": {
|
|
180
|
+
"evidence": "근거:",
|
|
181
|
+
"supporting-evidence": "뒷받침하는 근거:",
|
|
182
|
+
"id": "아이디",
|
|
183
|
+
"name": "이름",
|
|
184
|
+
"kind": "종류",
|
|
185
|
+
"status": "상태",
|
|
186
|
+
"source": "출처",
|
|
187
|
+
"subject": "제목",
|
|
188
|
+
"answer": "답변",
|
|
189
|
+
"disposition": "처리",
|
|
190
|
+
"sha": "SHA",
|
|
191
|
+
"order": "순서",
|
|
192
|
+
"plan-step": "계획 단계",
|
|
193
|
+
"proposed-by": "제안",
|
|
194
|
+
"lens": "렌즈",
|
|
195
|
+
"result": "결과",
|
|
196
|
+
"version": "버전",
|
|
197
|
+
"version-source": "버전 출처",
|
|
198
|
+
"symbol": "심볼",
|
|
199
|
+
"owner": "소유",
|
|
200
|
+
"adapter": "어댑터",
|
|
201
|
+
"direction": "방향",
|
|
202
|
+
"area": "영역",
|
|
203
|
+
"confidence": "확신도",
|
|
204
|
+
"impact": "영향",
|
|
205
|
+
"effort": "노력",
|
|
206
|
+
"risk": "위험",
|
|
207
|
+
"checked": "확인함",
|
|
208
|
+
"none": "없음",
|
|
209
|
+
"coverage-percent": "커버리지",
|
|
210
|
+
"scope-precision-percent": "범위 정밀도"
|
|
169
211
|
},
|
|
170
212
|
"visualizations": {
|
|
171
213
|
"component": "구성 요소",
|
|
@@ -201,7 +243,8 @@
|
|
|
201
243
|
"what-this-does-to-operations": "운영에 미치는 영향",
|
|
202
244
|
"area": "영역",
|
|
203
245
|
"impact": "영향",
|
|
204
|
-
"there-is-no-operational-impact": "운영에 미치는 영향이 없습니다."
|
|
246
|
+
"there-is-no-operational-impact": "운영에 미치는 영향이 없습니다.",
|
|
247
|
+
"unsettled": "미결"
|
|
205
248
|
},
|
|
206
249
|
"error-analysis": {
|
|
207
250
|
"what-you-saw": "관측된 증상",
|
|
@@ -217,7 +260,8 @@
|
|
|
217
260
|
"signal-that-rejects-it": "기각하는 신호:",
|
|
218
261
|
"next-step": "다음 단계",
|
|
219
262
|
"recommended-task": "권장 태스크",
|
|
220
|
-
"the-cause-this-rests-on": "이 판단이 근거하는 원인"
|
|
263
|
+
"the-cause-this-rests-on": "이 판단이 근거하는 원인",
|
|
264
|
+
"run": "실행"
|
|
221
265
|
},
|
|
222
266
|
"feature-analysis": {
|
|
223
267
|
"feature-overview": "기능 개요",
|
|
@@ -234,7 +278,10 @@
|
|
|
234
278
|
"nothing-was-recorded": "기록된 것이 없습니다.",
|
|
235
279
|
"state-once-it-is-done": "끝난 뒤의 상태",
|
|
236
280
|
"permissions-and-flags": "권한과 플래그",
|
|
237
|
-
"non-functional-concerns": "비기능 요건"
|
|
281
|
+
"non-functional-concerns": "비기능 요건",
|
|
282
|
+
"on-failure": "실패 시:",
|
|
283
|
+
"tests": "테스트:",
|
|
284
|
+
"gaps": "공백:"
|
|
238
285
|
},
|
|
239
286
|
"final-verification": {
|
|
240
287
|
"verification-verdict": "검증 판정",
|
|
@@ -276,7 +323,15 @@
|
|
|
276
323
|
"candidate": "후보",
|
|
277
324
|
"disposition": "처리",
|
|
278
325
|
"reason": "이유",
|
|
279
|
-
"no-audit-entries": "병합되거나 탈락한 후보가 없습니다."
|
|
326
|
+
"no-audit-entries": "병합되거나 탈락한 후보가 없습니다.",
|
|
327
|
+
"selection-status": "선택 상태",
|
|
328
|
+
"mode": "모드",
|
|
329
|
+
"routing": "라우팅",
|
|
330
|
+
"preselected-direction": "미리 고른 방향",
|
|
331
|
+
"option-id": "옵션 아이디",
|
|
332
|
+
"direction": "방향",
|
|
333
|
+
"confirmation-evidence": "확인 근거",
|
|
334
|
+
"citation": "인용"
|
|
280
335
|
},
|
|
281
336
|
"implementation-planning": {
|
|
282
337
|
"what-the-plan-is-for": "이 계획이 하려는 것",
|
|
@@ -355,7 +410,24 @@
|
|
|
355
410
|
"what-each-agent-did": "에이전트별 수행 내용",
|
|
356
411
|
"commands-and-evidence": "명령과 근거",
|
|
357
412
|
"unblock-condition": "승인 해제 조건:",
|
|
358
|
-
"agent-evidence": "에이전트 근거:"
|
|
413
|
+
"agent-evidence": "에이전트 근거:",
|
|
414
|
+
"selected-direction": "선택한 방향",
|
|
415
|
+
"source-report": "원본 보고",
|
|
416
|
+
"snapshot": "스냅샷",
|
|
417
|
+
"direction-realization": "방향 구현",
|
|
418
|
+
"core-mechanism": "핵심 메커니즘",
|
|
419
|
+
"interfaces": "인터페이스",
|
|
420
|
+
"plan-coverage": "계획 커버리지",
|
|
421
|
+
"coverage-percent": "커버리지",
|
|
422
|
+
"scope-precision-percent": "범위 정밀도",
|
|
423
|
+
"direction-invalidated": "방향 무효화",
|
|
424
|
+
"code-evidence": "코드 근거",
|
|
425
|
+
"re-entry-route": "재진입 경로",
|
|
426
|
+
"original-requirement": "원래 요구사항",
|
|
427
|
+
"stages": "stage",
|
|
428
|
+
"status": "상태",
|
|
429
|
+
"extract": "추출",
|
|
430
|
+
"keep": "그대로 둠"
|
|
359
431
|
},
|
|
360
432
|
"implementation": {
|
|
361
433
|
"what-was-delivered": "무엇을 만들었나",
|
|
@@ -366,6 +438,7 @@
|
|
|
366
438
|
"implemented-by": "구현한 곳",
|
|
367
439
|
"verification-result": "검증 결과",
|
|
368
440
|
"independent-check": "독립 검증:",
|
|
441
|
+
"exit-code": "종료 코드",
|
|
369
442
|
"what-is-left": "남은 것",
|
|
370
443
|
"nothing-was-changed-outside-the-plan": "계획 밖에서 바뀐 것이 없습니다.",
|
|
371
444
|
"commits-delivered": "만들어진 commit",
|
|
@@ -453,6 +526,7 @@
|
|
|
453
526
|
"pr-result": "PR 결과:",
|
|
454
527
|
"pull-request-open": "Pull request 열기",
|
|
455
528
|
"conflict-verdict": "충돌 판정",
|
|
529
|
+
"base-branch": "베이스 브랜치:",
|
|
456
530
|
"commits-delivered": "만들어진 commit",
|
|
457
531
|
"there-are-no-commits": "commit 이 없습니다.",
|
|
458
532
|
"commit": "commit",
|
|
@@ -479,7 +553,11 @@
|
|
|
479
553
|
"next-task": "다음 태스크:",
|
|
480
554
|
"this-requirements-task-stands-alone-nothing": "이 요구사항 태스크는 독립적입니다. 선행 태스크가 없습니다.",
|
|
481
555
|
"decisions-that-are-yours": "사용자가 결정할 것",
|
|
482
|
-
"no-further-decision-is-needed": "추가로 결정할 것이 없습니다."
|
|
556
|
+
"no-further-decision-is-needed": "추가로 결정할 것이 없습니다.",
|
|
557
|
+
"settled": "확정",
|
|
558
|
+
"decision-needed": "결정 필요",
|
|
559
|
+
"glossary": "용어집",
|
|
560
|
+
"decision-record": "결정 기록"
|
|
483
561
|
}
|
|
484
562
|
}
|
|
485
563
|
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
{% if state.show_option_selector %}<label for="approval-option">{{ t('macros.forms.implementation-option') }}</label>
|
|
32
32
|
<select id="approval-option"{% if state.disabled_reason %} disabled{% endif %}>
|
|
33
33
|
{% for name in state.option_names %}
|
|
34
|
-
{% if name == state.recommended_option %}<option data-recommended="true" selected value="{{ name }}">{{ name | inline_code }} (recommended)</option>{% else %}<option value="{{ name }}">{{ name | inline_code }}</option>{% endif %}
|
|
34
|
+
{% if name == state.recommended_option %}<option data-recommended="true" selected value="{{ name }}">{{ name | inline_code }} ({{ t('macros.forms.recommended') }})</option>{% else %}<option value="{{ name }}">{{ name | inline_code }}</option>{% endif %}
|
|
35
35
|
{% endfor %}
|
|
36
36
|
</select>{% endif %}
|
|
37
37
|
<label for="plan-decision-reason">{{ t('macros.forms.why-required-for-changes-or-rejection') }}</label>
|
|
@@ -43,69 +43,88 @@
|
|
|
43
43
|
|
|
44
44
|
{% macro direction_selection(state) -%}
|
|
45
45
|
<section id="direction-selection" data-report-section="direction-selection">
|
|
46
|
-
<h2>
|
|
47
|
-
<fieldset><legend>
|
|
46
|
+
<h2>{{ t('macros.forms.select-an-implementation-direction') }}</h2>
|
|
47
|
+
<fieldset><legend>{{ t('macros.forms.direction') }}</legend>
|
|
48
48
|
{% for option in state.rankedOptions %}
|
|
49
|
-
<input id="direction-selection-{{ option.id }}" type="radio" name="direction-selection-option" value="{{ option.id }}" data-option-name="{{ option.name }}" required><label for="direction-selection-{{ option.id }}">{{ option.id }} · {{ option.name | inline_code }}{% if option.id == state.recommendedOptionId %} (recommended){% endif %}</label>
|
|
49
|
+
<input id="direction-selection-{{ option.id }}" type="radio" name="direction-selection-option" value="{{ option.id }}" data-option-name="{{ option.name }}" required><label for="direction-selection-{{ option.id }}">{{ option.id | inline_code }} · {{ option.name | inline_code }}{% if option.id == state.recommendedOptionId %} ({{ t('macros.forms.recommended') }}){% endif %}</label>
|
|
50
50
|
{% endfor %}
|
|
51
51
|
</fieldset>
|
|
52
|
-
<input id="direction-selection-confirmed" type="checkbox" required><label for="direction-selection-confirmed">
|
|
53
|
-
<label for="direction-selection-note">
|
|
54
|
-
<label for="direction-selection-constraints">
|
|
52
|
+
<input id="direction-selection-confirmed" type="checkbox" required><label for="direction-selection-confirmed">{{ t('macros.forms.confirmed') }}</label>
|
|
53
|
+
<label for="direction-selection-note">{{ t('macros.forms.selection-note') }}</label><textarea id="direction-selection-note" rows="3"></textarea>
|
|
54
|
+
<label for="direction-selection-constraints">{{ t('macros.forms.constraints') }}</label><textarea id="direction-selection-constraints" rows="3"></textarea>
|
|
55
55
|
</section>
|
|
56
56
|
{%- endmacro %}
|
|
57
57
|
|
|
58
|
+
{% macro clarification_article(row, compact=false) -%}
|
|
59
|
+
{% set is_closed = row.status in ['resolved', 'obsolete'] %}
|
|
60
|
+
{% set approval_context = row.approvalContext | default(None) %}
|
|
61
|
+
{% set resolution = row.resolution | default(None) %}
|
|
62
|
+
{% set options = row.options | default([]) %}
|
|
63
|
+
<article class="clarification-item{% if compact %} is-closed{% endif %}" id="id-{{ row.id }}" data-response-id="{{ row.id }}" data-kind="{{ row.kind }}" data-status="{{ row.status }}">
|
|
64
|
+
{% if compact %}<details><summary>{{ row.id | inline_code }} · {{ row.status }}</summary>{% endif %}
|
|
65
|
+
<p class="eyebrow">{{ row.id | inline_code }} · {{ row.kind }}</p>
|
|
66
|
+
{{ row.statement | paragraphs }}
|
|
67
|
+
<dl class="clarification-expected"><dt>{{ t('macros.forms.answer-as') }}</dt><dd>{{ row.expectedForm | inline_code }}</dd></dl>
|
|
68
|
+
{% if approval_context %}
|
|
69
|
+
<div class="approval-context" data-approval-classification="{{ approval_context.classification }}">
|
|
70
|
+
<p class="eyebrow">{{ approval_context.classification }}</p>
|
|
71
|
+
<p><strong>{{ t('tasks.implementation-planning.unblock-condition') }}</strong> {{ approval_context.unblockCondition | inline_code }}</p>
|
|
72
|
+
{% set check_refs = resolution.checkRefs if resolution else approval_context.activityIds | default([]) %}
|
|
73
|
+
{% if check_refs %}<p><strong>{{ t('tasks.implementation-planning.agent-evidence') }}</strong>
|
|
74
|
+
{% for activity_id in check_refs %}<a href="#id-{{ activity_id }}">{{ activity_id }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
|
|
75
|
+
</p>{% endif %}
|
|
76
|
+
</div>
|
|
77
|
+
{% endif %}
|
|
78
|
+
{% if options %}
|
|
79
|
+
<ol class="clarification-options">
|
|
80
|
+
{% for option in options %}
|
|
81
|
+
<li class="clarification-option{% if option.role == 'recommended' %} is-recommended{% endif %}">
|
|
82
|
+
<p class="clarification-option-answer">{{ option.answer }}{% if option.role == 'recommended' %} <span class="badge">{{ t('macros.forms.recommended') }}</span>{% endif %}</p>
|
|
83
|
+
{% if option.disposition | default(None) %}<p class="clarification-option-disposition"><code>{{ option.disposition }}</code></p>{% endif %}
|
|
84
|
+
<p class="clarification-option-rationale">{{ option.rationale }}</p>
|
|
85
|
+
<dl class="clarification-option-impact">
|
|
86
|
+
<dt>{{ t('macros.forms.scope-impact') }}</dt><dd>{% if option.reach | default(None) %}{{ option.reach }}{% if option.scopeEffects | default([]) %}, {{ option.scopeEffects | join(', ') }}{% endif %}{% else %}{{ option.scopeImpact | join(', ') }}{% endif %}</dd>
|
|
87
|
+
<dt>{{ t('macros.forms.added-work') }}</dt><dd>{{ option.addedWork }}</dd>
|
|
88
|
+
<dt>{{ t('macros.forms.direction-change') }}</dt><dd>{{ option.directionChange }}</dd>
|
|
89
|
+
</dl>
|
|
90
|
+
</li>
|
|
91
|
+
{% endfor %}
|
|
92
|
+
</ol>
|
|
93
|
+
{% endif %}
|
|
94
|
+
<label for="response-{{ row.id }}">{{ t('macros.forms.your-answer-to-id') | replace('{id}', row.id) }}</label>
|
|
95
|
+
{% if row.kind == 'decision' and approval_context and options %}
|
|
96
|
+
<select id="response-{{ row.id }}" data-response-id="{{ row.id }}"{% if is_closed %} disabled{% endif %}>
|
|
97
|
+
<option value="">{{ t('macros.forms.choose-one') }}</option>
|
|
98
|
+
{% for option in options %}<option value="{{ option.answer }}" data-disposition="{{ option.disposition | default('') }}"{% if option.role == 'recommended' %} data-recommended="true"{% endif %}{% if row.userInput | default('') == option.answer %} selected{% endif %}>{{ option.answer }}</option>{% endfor %}
|
|
99
|
+
</select>
|
|
100
|
+
{% else %}
|
|
101
|
+
<textarea id="response-{{ row.id }}" data-response-id="{{ row.id }}" rows="4"{% if is_closed %} disabled{% endif %}>{{ row.userInput | default('') }}</textarea>
|
|
102
|
+
{% endif %}
|
|
103
|
+
{% if compact %}</details>{% endif %}
|
|
104
|
+
</article>
|
|
105
|
+
{%- endmacro %}
|
|
106
|
+
|
|
58
107
|
{% macro clarification_responses(items) -%}
|
|
59
108
|
{% if items %}
|
|
60
|
-
|
|
61
|
-
|
|
109
|
+
{% set ns = namespace(open=[], closed=[]) %}
|
|
110
|
+
{% for row in items %}
|
|
111
|
+
{% if row.status in ['open', 'answered'] %}
|
|
112
|
+
{% set ns.open = ns.open + [row] %}
|
|
113
|
+
{% else %}
|
|
114
|
+
{% set ns.closed = ns.closed + [row] %}
|
|
115
|
+
{% endif %}
|
|
116
|
+
{% endfor %}
|
|
117
|
+
<section class="clarification-responses" data-report-section="clarification-responses" aria-label="{{ t('macros.forms.questions-waiting-on-you') if ns.open else t('macros.forms.answered-questions') }}">
|
|
118
|
+
{% if ns.open %}
|
|
119
|
+
<h2>{{ t('macros.forms.count-questions-waiting-on-you') | replace('{count}', ns.open | length) }}</h2>
|
|
62
120
|
<p class="clarification-lede">{{ t('macros.forms.the-code-alone-could-not-settle-these-fill-i') }} <strong>{{ t('macros.forms.export-my-answers') }}</strong> {{ t('macros.forms.at-the-foot-of-the-page') }}</p>
|
|
63
|
-
{% for row in
|
|
64
|
-
{%
|
|
65
|
-
{%
|
|
66
|
-
{%
|
|
67
|
-
{%
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{{ row.statement | paragraphs }}
|
|
71
|
-
<dl class="clarification-expected"><dt>{{ t('macros.forms.answer-as') }}</dt><dd>{{ row.expectedForm | inline_code }}</dd></dl>
|
|
72
|
-
{% if approval_context %}
|
|
73
|
-
<div class="approval-context" data-approval-classification="{{ approval_context.classification }}">
|
|
74
|
-
<p class="eyebrow">{{ approval_context.classification }}</p>
|
|
75
|
-
<p><strong>{{ t('tasks.implementation-planning.unblock-condition') }}</strong> {{ approval_context.unblockCondition | inline_code }}</p>
|
|
76
|
-
{% set check_refs = resolution.checkRefs if resolution else approval_context.activityIds | default([]) %}
|
|
77
|
-
{% if check_refs %}<p><strong>{{ t('tasks.implementation-planning.agent-evidence') }}</strong>
|
|
78
|
-
{% for activity_id in check_refs %}<a href="#id-{{ activity_id }}">{{ activity_id }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
|
|
79
|
-
</p>{% endif %}
|
|
80
|
-
</div>
|
|
81
|
-
{% endif %}
|
|
82
|
-
{% if options %}
|
|
83
|
-
<ol class="clarification-options">
|
|
84
|
-
{% for option in options %}
|
|
85
|
-
<li class="clarification-option{% if option.role == 'recommended' %} is-recommended{% endif %}">
|
|
86
|
-
<p class="clarification-option-answer">{{ option.answer }}{% if option.role == 'recommended' %} <span class="badge">{{ t('macros.forms.recommended') }}</span>{% endif %}</p>
|
|
87
|
-
{% if option.disposition | default(None) %}<p class="clarification-option-disposition"><code>{{ option.disposition }}</code></p>{% endif %}
|
|
88
|
-
<p class="clarification-option-rationale">{{ option.rationale }}</p>
|
|
89
|
-
<dl class="clarification-option-impact">
|
|
90
|
-
<dt>{{ t('macros.forms.scope-impact') }}</dt><dd>{% if option.reach | default(None) %}{{ option.reach }}{% if option.scopeEffects | default([]) %}, {{ option.scopeEffects | join(', ') }}{% endif %}{% else %}{{ option.scopeImpact | join(', ') }}{% endif %}</dd>
|
|
91
|
-
<dt>{{ t('macros.forms.added-work') }}</dt><dd>{{ option.addedWork }}</dd>
|
|
92
|
-
<dt>{{ t('macros.forms.direction-change') }}</dt><dd>{{ option.directionChange }}</dd>
|
|
93
|
-
</dl>
|
|
94
|
-
</li>
|
|
95
|
-
{% endfor %}
|
|
96
|
-
</ol>
|
|
97
|
-
{% endif %}
|
|
98
|
-
<label for="response-{{ row.id }}">{{ t('macros.forms.your-answer-to-id') | replace('{id}', row.id) }}</label>
|
|
99
|
-
{% if row.kind == 'decision' and approval_context and options %}
|
|
100
|
-
<select id="response-{{ row.id }}" data-response-id="{{ row.id }}"{% if is_closed %} disabled{% endif %}>
|
|
101
|
-
<option value="">{{ t('macros.forms.choose-one') }}</option>
|
|
102
|
-
{% for option in options %}<option value="{{ option.answer }}" data-disposition="{{ option.disposition | default('') }}"{% if option.role == 'recommended' %} data-recommended="true"{% endif %}{% if row.userInput | default('') == option.answer %} selected{% endif %}>{{ option.answer }}</option>{% endfor %}
|
|
103
|
-
</select>
|
|
104
|
-
{% else %}
|
|
105
|
-
<textarea id="response-{{ row.id }}" data-response-id="{{ row.id }}" rows="4"{% if is_closed %} disabled{% endif %}>{{ row.userInput | default('') }}</textarea>
|
|
106
|
-
{% endif %}
|
|
107
|
-
</article>
|
|
108
|
-
{% endfor %}
|
|
121
|
+
{% for row in ns.open %}{{ clarification_article(row) }}{% endfor %}
|
|
122
|
+
{% endif %}
|
|
123
|
+
{% if ns.closed %}
|
|
124
|
+
{% if ns.open %}<h3>{{ t('macros.forms.count-answered-questions') | replace('{count}', ns.closed | length) }}</h3>
|
|
125
|
+
{% else %}<h2>{{ t('macros.forms.count-answered-questions') | replace('{count}', ns.closed | length) }}</h2>{% endif %}
|
|
126
|
+
{% for row in ns.closed %}{{ clarification_article(row, compact=true) }}{% endfor %}
|
|
127
|
+
{% endif %}
|
|
109
128
|
</section>
|
|
110
129
|
{% endif %}
|
|
111
130
|
{%- endmacro %}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% macro narrative(value, field_name) -%}
|
|
2
2
|
<div class="narrative" data-report-field="{{ field_name }}">
|
|
3
3
|
{{ value.text | paragraphs }}
|
|
4
|
-
<p class="evidence-refs">
|
|
4
|
+
<p class="evidence-refs">{{ t('macros.layout.evidence') }} {{ value.evidenceRefs | evidence_refs }}</p>
|
|
5
5
|
</div>
|
|
6
6
|
{%- endmacro %}
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
{% macro summary_card(title, body, tone='neutral', anchor='') -%}
|
|
28
28
|
<article class="summary-card tone-{{ tone }}"{% if anchor %} id="id-{{ anchor }}"{% endif %}>
|
|
29
|
-
{% if title %}<h3>{{ title }}</h3>{% endif %}
|
|
29
|
+
{% if title %}<h3>{{ title | inline_code }}</h3>{% endif %}
|
|
30
30
|
<p>{{ body | inline_code }}</p>
|
|
31
31
|
</article>
|
|
32
32
|
{%- endmacro %}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<thead><tr><th>{{ t('macros.visualizations.component') }}</th>{% if show_detail %}<th>{{ t('macros.visualizations.what-it-does') }}</th>{% endif %}{% if show_paths %}<th>{{ t('macros.visualizations.paths') }}</th>{% endif %}</tr></thead>
|
|
13
13
|
<tbody>
|
|
14
14
|
{% for node in model.nodes %}
|
|
15
|
-
<tr{% if anchor_nodes %} id="id-{{ node.id }}"{% endif %} data-fallback-id="{{ node.id }}">{{ row_key(pairs=[(
|
|
15
|
+
<tr{% if anchor_nodes %} id="id-{{ node.id }}"{% endif %} data-fallback-id="{{ node.id }}">{{ row_key(pairs=[(t('macros.layout.id'), node.id), (t('macros.layout.name'), node.label), (t('macros.layout.kind'), node.note)]) }}{% if show_detail %}<td>{{ node.detail | inline_code }}</td>{% endif %}{% if show_paths %}<td>{% for path in node.paths %}<code>{{ path }}</code>{% if not loop.last %} {% endif %}{% endfor %}</td>{% endif %}</tr>
|
|
16
16
|
{% endfor %}
|
|
17
17
|
</tbody>
|
|
18
18
|
</table>
|