|
|
@@ -5,12 +5,15 @@
|
|
|
<pstm-template>main</pstm-template>
|
|
|
<script>
|
|
|
// The goal page: supervision surface of one goal — status head
|
|
|
- // with lifecycle actions, the locked brief, the approved plan
|
|
|
- // (rejected revisions under the historical-blocks expander), the
|
|
|
+ // with lifecycle actions, branch/push-state chips, the agent's
|
|
|
+ // live progress feed and current activity, the locked brief, the
|
|
|
+ // approved plan (revision history behind the expander), the
|
|
|
// task status strip (its buttons filter the task list), the
|
|
|
// supervision narrative, the comment thread with
|
|
|
// selection-quoting, the completion review and the goal agent's
|
|
|
- // runs. The status strip's filter lives client-side in
|
|
|
+ // runs. Every long-form body (brief, plans, reports, blocks,
|
|
|
+ // comments, events) renders as markdown via stm-markdown. The
|
|
|
+ // status strip's filter lives client-side in
|
|
|
// window.goalTaskFilter; clicking a strip button re-runs the
|
|
|
// sealed refresh action, and the filter rides the re-render.
|
|
|
if (window.statum) {
|
|
|
@@ -67,16 +70,17 @@
|
|
|
</script>
|
|
|
</head>
|
|
|
<body>
|
|
|
- <div class="page">
|
|
|
+ <div class="page goal-page">
|
|
|
<p><a href="/goals">← Goals</a></p>
|
|
|
- <h2 stm-if="goal.exists">#<span stm-text="goal.id">id</span> —
|
|
|
+ <h2 stm-if="goal.exists"><span class="goal-icon">🎯</span> #<span stm-text="goal.id">id</span> —
|
|
|
<span stm-text="goal.title">title</span></h2>
|
|
|
<p stm-if="!goal.exists" class="muted">Goal not found.</p>
|
|
|
|
|
|
<div stm-if="goal.exists">
|
|
|
- <!-- Status head: lifecycle badge, branch pair, priority and
|
|
|
- the lifecycle actions. -->
|
|
|
- <section class="card">
|
|
|
+ <!-- Status head: lifecycle badge, branch pair with the
|
|
|
+ daemon-reported push-state chips, priority, the
|
|
|
+ assigned agent saddle and the lifecycle actions. -->
|
|
|
+ <section class="card goal-head">
|
|
|
<div class="card-head">
|
|
|
<h3>Status</h3>
|
|
|
<span class="badge badge-yeehaw status-corner"
|
|
|
@@ -85,7 +89,16 @@
|
|
|
<p><span stm-attribute.class="'badge badge-' + goal.status" stm-text="goal.display">status</span>
|
|
|
· goal branch <code stm-text="goal.branch_name">branch</code>
|
|
|
<span class="muted">from</span> <code stm-text="goal.base_branch">base</code>
|
|
|
- · priority <strong stm-text="goal.priority">3</strong></p>
|
|
|
+ · priority <strong stm-text="goal.priority">3</strong>
|
|
|
+ <span stm-if="goal.agent_saddle.length > 0"> · agent saddle
|
|
|
+ <strong stm-text="goal.agent_saddle">saddle</strong></span></p>
|
|
|
+ <p stm-if="goal.push_branches.length > 0">Goal branches:
|
|
|
+ <span stm-for-branch-in="goal.push_branches">
|
|
|
+ <code stm-text="branch.branch">b</code>
|
|
|
+ <span stm-attribute.class="branch.pushed ? 'badge badge-done' : 'badge badge-failed'"
|
|
|
+ stm-text="branch.pushed ? 'pushed' : 'unpushed'">state</span>
|
|
|
+ </span>
|
|
|
+ <span class="muted">(the daemon's /status report)</span></p>
|
|
|
<p class="muted">Project:
|
|
|
<a stm-attribute.href="'/projects/' + goal.project_id" stm-text="goal.project_name">project</a>
|
|
|
· Created <span stm-text="goal.created_display">when</span>
|
|
|
@@ -110,11 +123,46 @@
|
|
|
task events queue and coalesce into the resume.</p>
|
|
|
</section>
|
|
|
|
|
|
+ <!-- The agent's live progress feed (task-page pattern):
|
|
|
+ the newest line leads, its history behind the
|
|
|
+ expander. -->
|
|
|
+ <h3>Agent progress</h3>
|
|
|
+ <div stm-if="goal.progress.length > 0">
|
|
|
+ <p class="progress-latest" stm-text="goal.progress[0].summary">latest</p>
|
|
|
+ <p class="muted" stm-text="'reported ' + goal.progress[0].when_display">when</p>
|
|
|
+ <details class="history-expander" stm-if="goal.progress.length > 1">
|
|
|
+ <summary>Show history (<span stm-text="goal.progress.length">0</span> updates)</summary>
|
|
|
+ <ul class="progress-history">
|
|
|
+ <li stm-for-item-in="goal.progress">
|
|
|
+ <span class="muted" stm-text="item.when_display">when</span> —
|
|
|
+ <span stm-text="item.summary">summary</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </details>
|
|
|
+ </div>
|
|
|
+ <p stm-if="goal.progress.length == 0" class="muted">No progress reports yet — the goal
|
|
|
+ agent reports via <code>saddle progress-update</code>.</p>
|
|
|
+
|
|
|
+ <!-- Current activity (task-page parity): what the agent's
|
|
|
+ open round is doing right now, plus its saddle's
|
|
|
+ health. -->
|
|
|
+ <section class="card goal-activity" stm-if="goal.run_task_id > 0">
|
|
|
+ <h3>Current activity</h3>
|
|
|
+ <p stm-if="goal.current_command.length > 0">
|
|
|
+ <span class="badge badge-working" stm-if="goal.current_command_running">running</span>
|
|
|
+ <code stm-text="goal.current_command">command</code>
|
|
|
+ <span class="muted" stm-text="goal.current_command_display">when</span></p>
|
|
|
+ <p stm-if="goal.current_command.length == 0" class="muted">No recorded activity in
|
|
|
+ the current round — the raw terminal carries the live stream.</p>
|
|
|
+ <p stm-if="goal.saddle_health.length > 0" class="muted"
|
|
|
+ stm-text="goal.saddle_health">health</p>
|
|
|
+ </section>
|
|
|
+
|
|
|
<!-- The locked brief. -->
|
|
|
<section class="card">
|
|
|
<h3>Initial brief
|
|
|
<span class="muted" stm-if="goal.started_display.length > 0">(locked)</span></h3>
|
|
|
- <div class="rfc-body goal-body" data-brief-body stm-text="goal.brief">brief</div>
|
|
|
+ <div class="md rfc-body goal-body" data-brief-body stm-markdown="goal.brief">brief</div>
|
|
|
</section>
|
|
|
|
|
|
<!-- Involved projects. -->
|
|
|
@@ -144,21 +192,22 @@
|
|
|
</section>
|
|
|
|
|
|
<!-- The plan: the approved markdown; the pending review;
|
|
|
- rejected revisions behind the historical expander. -->
|
|
|
+ the revision history (approved + rejected) behind the
|
|
|
+ expander, task-page pattern. -->
|
|
|
<section class="card">
|
|
|
<h3>Plan</h3>
|
|
|
- <div stm-if="goal.plan.length > 0" class="rfc-body goal-body" data-plan-body
|
|
|
- stm-text="goal.plan">plan</div>
|
|
|
+ <div stm-if="goal.plan.length > 0" class="md rfc-body goal-body" data-plan-body
|
|
|
+ stm-markdown="goal.plan">plan</div>
|
|
|
<p stm-if="goal.plan.length == 0 && goal.plan_pending_block == null"
|
|
|
class="muted">No approved plan yet.</p>
|
|
|
|
|
|
<div stm-if="goal.plan_pending_block != null && goal.plan_pending_block != false" class="plan-review">
|
|
|
<h4>Plan submitted for review</h4>
|
|
|
- <div class="rfc-body goal-body" stm-text="goal.plan_pending_block.body">revision</div>
|
|
|
+ <div class="md rfc-body goal-body" stm-markdown="goal.plan_pending_block.body">revision</div>
|
|
|
<form stm-action="goal.plan_pending_block.answer_action" class="inline">
|
|
|
<input type="hidden" name="answer"
|
|
|
value="Plan approved. Proceed with implementation.">
|
|
|
- <button type="submit" class="primary">Approve plan</button>
|
|
|
+ <button type="submit" class="approve">Approve plan</button>
|
|
|
</form>
|
|
|
<details>
|
|
|
<summary>Reject with feedback</summary>
|
|
|
@@ -166,7 +215,7 @@
|
|
|
<div class="form-row">
|
|
|
<textarea name="answer" rows="4" required
|
|
|
placeholder="What must change before approval?"></textarea></div>
|
|
|
- <button type="submit">Send feedback</button>
|
|
|
+ <button type="submit" class="reject">Send feedback</button>
|
|
|
</form>
|
|
|
</details>
|
|
|
</div>
|
|
|
@@ -175,10 +224,12 @@
|
|
|
<summary>Plan revisions & feedback (<span
|
|
|
stm-text="goal.plan_revisions.length">0</span>)</summary>
|
|
|
<div stm-for-revision-in="goal.plan_revisions" class="plan-revision">
|
|
|
- <p class="muted" stm-text="'Revision #' + revision.id + ' — ' + revision.created_display">when</p>
|
|
|
+ <p><span stm-attribute.class="'badge ' + (revision.approved ? 'badge-done' : (revision.answered ? 'badge-failed' : 'badge-plan'))"
|
|
|
+ stm-text="revision.approved ? 'approved' : (revision.answered ? 'rejected' : 'pending')">verdict</span>
|
|
|
+ <span class="muted" stm-text="'Revision #' + revision.id + ' — ' + revision.created_display">when</span></p>
|
|
|
<details>
|
|
|
<summary>Submitted markdown</summary>
|
|
|
- <div class="rfc-body" stm-text="revision.body">body</div>
|
|
|
+ <div class="md rfc-body" stm-markdown="revision.body">body</div>
|
|
|
</details>
|
|
|
<blockquote stm-if="revision.answered" class="term-comment-quote">
|
|
|
<span stm-text="revision.answered_by">who</span>:
|
|
|
@@ -187,7 +238,7 @@
|
|
|
</details>
|
|
|
</section>
|
|
|
|
|
|
- <!-- Completion review: the report, push state, compare link. -->
|
|
|
+ <!-- Completion review: the report, compare link. -->
|
|
|
<section class="card" stm-if="goal.completion_pending">
|
|
|
<h3>Completion review</h3>
|
|
|
<p stm-if="goal.push_branches.length > 0">Goal branches:
|
|
|
@@ -195,15 +246,14 @@
|
|
|
<code stm-text="branch.branch">b</code>
|
|
|
<span stm-attribute.class="branch.pushed ? 'badge badge-done' : 'badge badge-failed'"
|
|
|
stm-text="branch.pushed ? 'pushed' : 'unpushed'">state</span>
|
|
|
- </span>
|
|
|
- <span class="muted">(reported by the daemon's /status)</span></p>
|
|
|
+ </span></p>
|
|
|
<p><a stm-if="goal.compare_url.length > 0" stm-attribute.href="goal.compare_url"
|
|
|
target="_blank" rel="noopener">Compare changes</a></p>
|
|
|
- <div class="rfc-body goal-body" stm-text="goal.completion_report">report</div>
|
|
|
+ <div class="md rfc-body goal-body" stm-markdown="goal.completion_report">report</div>
|
|
|
<form stm-action="goal.completion_pending_block.answer_action" class="inline">
|
|
|
<input type="hidden" name="answer"
|
|
|
value="Review approved. Continue with the task.">
|
|
|
- <button type="submit" class="primary">Accept goal</button>
|
|
|
+ <button type="submit" class="approve">Accept goal</button>
|
|
|
</form>
|
|
|
<details>
|
|
|
<summary>Request changes</summary>
|
|
|
@@ -211,7 +261,7 @@
|
|
|
<div class="form-row">
|
|
|
<textarea name="answer" rows="4" required
|
|
|
placeholder="What remains to be done?"></textarea></div>
|
|
|
- <button type="submit">Send feedback</button>
|
|
|
+ <button type="submit" class="reject">Send feedback</button>
|
|
|
</form>
|
|
|
</details>
|
|
|
</section>
|
|
|
@@ -260,7 +310,8 @@
|
|
|
</section>
|
|
|
|
|
|
<!-- The supervision narrative: one chronological feed of
|
|
|
- the goal agent's life. -->
|
|
|
+ the goal agent's life (markdown bodies — reports land
|
|
|
+ here whole). -->
|
|
|
<section class="card">
|
|
|
<h3>Supervision narrative</h3>
|
|
|
<p stm-if="goal.events.length == 0" class="muted">Nothing yet — start the goal.</p>
|
|
|
@@ -268,13 +319,13 @@
|
|
|
<span class="muted" stm-text="event.at_display">when</span>
|
|
|
<span stm-attribute.class="'badge badge-goal-' + event.kind"
|
|
|
stm-text="event.kind.replace('-', ' ')">kind</span>
|
|
|
- <span stm-text="event.text">text</span>
|
|
|
+ <div class="md goal-event-text" stm-markdown="event.text">text</div>
|
|
|
<a stm-if="event.task_id > 0"
|
|
|
stm-attribute.href="'/tasks/' + event.task_id">task</a>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
- <!-- Comments with selection-quoting. -->
|
|
|
+ <!-- Comments with selection-quoting (markdown bodies). -->
|
|
|
<section class="card">
|
|
|
<h3>Comments</h3>
|
|
|
<div stm-for-comment-in="goal.comments"
|
|
|
@@ -282,13 +333,13 @@
|
|
|
<strong stm-text="comment.author">author</strong>
|
|
|
<span class="muted" stm-text="comment.created_display">when</span>
|
|
|
<blockquote stm-if="comment.quote.length > 0" stm-text="comment.quote">quote</blockquote>
|
|
|
- <div stm-text="comment.body">body</div>
|
|
|
+ <div class="md" stm-markdown="comment.body">body</div>
|
|
|
</div>
|
|
|
<p stm-if="goal.comments.length == 0" class="muted">No comments yet.</p>
|
|
|
<form stm-action="goal.comment">
|
|
|
<div class="form-row"><label for="goal-comment-body">Add comment</label>
|
|
|
<textarea id="goal-comment-body" name="body" rows="3"
|
|
|
- placeholder="A comment for the goal agent"></textarea></div>
|
|
|
+ placeholder="A comment for the goal agent (markdown)"></textarea></div>
|
|
|
<button type="submit" class="primary">Comment</button>
|
|
|
</form>
|
|
|
<dialog id="quote-comment-dialog">
|
|
|
@@ -306,8 +357,8 @@
|
|
|
</dialog>
|
|
|
</section>
|
|
|
|
|
|
- <!-- The goal agent's blocks (questions/RFCs) with their
|
|
|
- answer forms. -->
|
|
|
+ <!-- The goal agent's blocks (questions/RFCs) with full
|
|
|
+ markdown bodies and their inline answer forms. -->
|
|
|
<section class="card" stm-if="goal.blocks.length > 0">
|
|
|
<h3>Goal agent blocks</h3>
|
|
|
<div stm-for-block-in="goal.blocks" class="goal-block">
|
|
|
@@ -317,7 +368,7 @@
|
|
|
<strong stm-text="block.question">question</strong>
|
|
|
<span class="muted" stm-text="block.created_display">when</span></p>
|
|
|
<div stm-if="block.show_body && block.body.length > 0"
|
|
|
- class="rfc-body goal-body" stm-text="block.body">body</div>
|
|
|
+ class="md rfc-body goal-body" stm-markdown="block.body">body</div>
|
|
|
<blockquote stm-if="block.answered" class="term-comment-quote">
|
|
|
<span stm-text="block.answered_by">who</span>:
|
|
|
<span stm-text="block.answer">answer</span></blockquote>
|
|
|
@@ -337,18 +388,22 @@
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
- <!-- Goal agent runs with terminal links (the session
|
|
|
- picker lives on the terminal page). -->
|
|
|
+ <!-- Goal agent runs: every round with its host saddle; the
|
|
|
+ terminal links open in a new tab (the session picker
|
|
|
+ lives on the terminal page). -->
|
|
|
<section class="card" stm-if="goal.runs.length > 0">
|
|
|
<h3>Goal agent runs</h3>
|
|
|
- <p><a stm-attribute.href="'/tasks/' + goal.run_task_id + '/terminal'">Terminal
|
|
|
+ <p><a stm-attribute.href="'/tasks/' + goal.run_task_id + '/terminal'"
|
|
|
+ target="_blank" rel="noopener">Terminal
|
|
|
(session picker)</a> <span class="muted">— run task
|
|
|
#<span stm-text="goal.run_task_id">id</span></span></p>
|
|
|
<table>
|
|
|
- <thead><tr><th>Run</th><th>Started</th><th>Ended</th><th>Outcome</th></tr></thead>
|
|
|
+ <thead><tr><th>Run</th><th>Saddle</th><th>Started</th><th>Ended</th><th>Outcome</th></tr></thead>
|
|
|
<tbody>
|
|
|
<tr stm-for-run-in="goal.runs">
|
|
|
- <td><a stm-attribute.href="run.terminal_url" stm-text="'session ' + run.id">run</a></td>
|
|
|
+ <td><a stm-attribute.href="run.terminal_url" target="_blank" rel="noopener"
|
|
|
+ stm-text="'session ' + run.id">run</a></td>
|
|
|
+ <td class="muted" stm-text="run.saddle_name">saddle</td>
|
|
|
<td class="muted" stm-text="run.started_display">when</td>
|
|
|
<td class="muted" stm-text="run.ended_display">when</td>
|
|
|
<td><span stm-if="run.open" class="badge badge-working">open</span>
|