Fix all integrations

This commit is contained in:
2026-03-08 22:08:55 +00:00
parent bca4d6898f
commit acedc01e83
58 changed files with 4120 additions and 960 deletions

View File

@@ -2,9 +2,13 @@
{% block content %}
<section class="section">
<div class="container">
<h1 class="title is-4">Codex Status</h1>
<p class="subtitle is-6">Global per-user Codex task-sync status, runs, and approvals.</p>
<div class="container gia-page-shell">
<div class="gia-page-header">
<div>
<h1 class="title is-4">Codex Status</h1>
<p class="subtitle is-6">Worker-backed task sync status, runs, and approvals for the canonical GIA task store.</p>
</div>
</div>
<article class="box">
<div class="codex-inline-stats">

View File

@@ -5,6 +5,11 @@
<div class="container">
<h1 class="title is-4">Command Routing</h1>
<p class="subtitle is-6">Configure commands, channel bindings, and per-command delivery in a predictable way.</p>
<p class="help">
Related controls:
<a href="{% url 'tasks_settings' %}">Task Automation</a> and
<a href="{% url 'permission_settings' %}">Security Permissions</a>.
</p>
{% if scope_service and scope_identifier %}
<article class="notification is-info is-light">
Scoped to this chat only: <strong>{{ scope_service }}</strong> · <code>{{ scope_identifier }}</code>

View File

@@ -190,13 +190,22 @@
data-person="{{ row.linked_person_name|default:'-'|lower }}"
data-detected="{{ row.detected_name|default:'-'|lower }}"
data-identifier="{{ row.identifier|lower }}"
data-search="{{ row.linked_person_name|default:'-'|lower }} {{ row.detected_name|default:'-'|lower }} {{ row.service|lower }} {{ row.identifier|lower }}">
data-search="{{ row.linked_person_name|default:'-'|lower }} {{ row.detected_name|default:'-'|lower }} {{ row.service|lower }} {{ row.identifier_search|default:row.identifier|lower }}">
<td data-discovered-col="0" class="discovered-col-0">{{ row.linked_person_name|default:"-" }}</td>
<td data-discovered-col="1" class="discovered-col-1">{{ row.detected_name|default:"-" }}</td>
<td data-discovered-col="2" class="discovered-col-2">
{{ row.service|title }}
</td>
<td data-discovered-col="3" class="discovered-col-3"><code>{{ row.identifier }}</code></td>
<td data-discovered-col="3" class="discovered-col-3">
<code>{{ row.identifier }}</code>
{% if row.identifier_aliases %}
<div class="is-size-7 has-text-grey mt-1">
{% for alias in row.identifier_aliases %}
<div><code>{{ alias }}</code></div>
{% endfor %}
</div>
{% endif %}
</td>
<td data-discovered-col="4" class="discovered-col-4">
{% if not row.linked_person %}
<div class="buttons are-small">

View File

@@ -48,12 +48,20 @@
<p class="help is-size-7 has-text-grey">This is separate from command-scope policy checks such as Require Trusted Fingerprint.</p>
</div>
<input type="hidden" name="encrypt_contact_messages_with_omemo" value="0">
<input type="hidden" name="encrypt_component_messages_with_omemo" value="0">
<div class="field mt-3">
<label class="checkbox">
<input type="checkbox" name="encrypt_component_messages_with_omemo" value="1"{% if security_settings.encrypt_component_messages_with_omemo %} checked{% endif %}>
Encrypt gateway component chat replies with OMEMO
</label>
<p class="help is-size-7 has-text-grey mt-1">Controls only gateway/component command replies (for example, <code>.tasks</code> or approvals) sent to your XMPP client.</p>
</div>
<div class="field mt-3">
<label class="checkbox">
<input type="checkbox" name="encrypt_contact_messages_with_omemo" value="1"{% if security_settings.encrypt_contact_messages_with_omemo %} checked{% endif %}>
Encrypt contact relay messages to your XMPP client with OMEMO
</label>
<p class="help is-size-7 has-text-grey mt-1">When enabled, relay text from contacts is sent with OMEMO when available. If disabled, relay text is sent in plaintext.</p>
<p class="help is-size-7 has-text-grey mt-1">Controls relayed contact chat text. Keep this off if you want normal contact chats while securing only component workflows.</p>
</div>
<button class="button is-link is-small" type="submit">Save</button>
</form>
@@ -194,7 +202,7 @@
<div class="box">
<h2 class="title is-6">Global Scope Override</h2>
<p class="is-size-7 has-text-grey mb-3">
This scope can force settings across all Command Security Scopes.
This scope can force settings across all Fine-Grained Security Scopes.
</p>
<div class="box" style="margin: 0; border: 1px solid rgba(60, 60, 60, 0.12);">
<form method="post">
@@ -341,7 +349,7 @@
{% endfor %}
</select>
</div>
<input class="input is-small" name="allowed_channel_pattern" value="{{ rule.pattern }}" placeholder="m@zm.is* or 1203*">
<input class="input is-small" name="allowed_channel_pattern" value="{{ rule.pattern }}" placeholder="user@example.test* or 1203*">
<button class="button is-small is-light is-danger channel-rule-remove" type="button">Remove</button>
</div>
{% endfor %}
@@ -454,7 +462,7 @@
{% endfor %}
</select>
</div>
<input class="input is-small scope-editable" data-lock-state="free" name="allowed_channel_pattern" value="{{ rule.pattern }}" placeholder="m@zm.is* or 1203*">
<input class="input is-small scope-editable" data-lock-state="free" name="allowed_channel_pattern" value="{{ rule.pattern }}" placeholder="user@example.test* or 1203*">
<button class="button is-small is-light is-danger channel-rule-remove scope-editable" data-lock-state="free" type="button">Remove</button>
</div>
{% endfor %}
@@ -516,7 +524,7 @@
{% endfor %}
</select>
</div>
<input class="input is-small scope-editable" data-lock-state="free" name="allowed_channel_pattern" value="" placeholder="m@zm.is* or 1203*">
<input class="input is-small scope-editable" data-lock-state="free" name="allowed_channel_pattern" value="" placeholder="user@example.test* or 1203*">
<button class="button is-small is-light is-danger channel-rule-remove scope-editable" data-lock-state="free" type="button">Remove</button>
</div>
</template>

View File

@@ -1,8 +1,12 @@
{% extends "base.html" %}
{% block content %}
<section class="section"><div class="container">
<h1 class="title is-4">Task #{{ task.reference_code }}: {{ task.title }}</h1>
<p class="subtitle is-6">{{ task.project.name }}{% if task.epic %} / {{ task.epic.name }}{% endif %} · {{ task.status_snapshot }}</p>
<section class="section"><div class="container gia-page-shell">
<div class="gia-page-header">
<div>
<h1 class="title is-4">Task #{{ task.reference_code }}: {{ task.title }}</h1>
<p class="subtitle is-6">{{ task.project.name }}{% if task.epic %} / {{ task.epic.name }}{% endif %} · {{ task.status_snapshot }}</p>
</div>
</div>
<p class="is-size-7 has-text-grey" style="margin-top:-0.65rem; margin-bottom: 0.65rem;">
Created by {{ task.creator_label|default:"Unknown" }}
{% if task.origin_message_id %}

View File

@@ -1,9 +1,13 @@
{% extends "base.html" %}
{% block content %}
<section class="section">
<div class="container">
<h1 class="title is-4">Task Inbox</h1>
<p class="subtitle is-6">Immutable tasks derived from chat activity.</p>
<div class="container gia-page-shell">
<div class="gia-page-header">
<div>
<h1 class="title is-4">Task Inbox</h1>
<p class="subtitle is-6">Canonical tasks live in GIA. Chats, XMPP, web UI, and agent tooling all operate on the same records.</p>
</div>
</div>
<div class="buttons" style="margin-bottom: 0.75rem;">
<a class="button is-small is-link is-light" href="{% url 'tasks_settings' %}{% if scope.person_id or scope.service or scope.identifier %}?{% if scope.person_id %}person={{ scope.person_id|urlencode }}{% endif %}{% if scope.service %}{% if scope.person_id %}&{% endif %}service={{ scope.service|urlencode }}{% endif %}{% if scope.identifier %}{% if scope.person_id or scope.service %}&{% endif %}identifier={{ scope.identifier|urlencode }}{% endif %}{% endif %}">Task Automation</a>
</div>
@@ -139,6 +143,60 @@
</article>
</div>
<div class="column">
<article class="box">
<div class="is-flex is-justify-content-space-between is-align-items-center" style="gap: 0.5rem; margin-bottom: 0.6rem; flex-wrap: wrap;">
<h2 class="title is-6" style="margin: 0;">Create Task</h2>
{% if scope.service or scope.identifier %}
<span class="tag task-ui-badge">{{ scope.service|default:"web" }}{% if scope.identifier %} · {{ scope.identifier }}{% endif %}</span>
{% else %}
<span class="tag task-ui-badge">web</span>
{% endif %}
</div>
<p class="help" style="margin-bottom: 0.65rem;">Use this to create canonical tasks directly from the web UI without relying on WhatsApp-derived source state.</p>
<form method="post">
{% csrf_token %}
<input type="hidden" name="action" value="task_create">
<input type="hidden" name="person" value="{{ scope.person_id }}">
<input type="hidden" name="service" value="{{ scope.service }}">
<input type="hidden" name="identifier" value="{{ scope.identifier }}">
<div class="columns is-multiline">
<div class="column is-7">
<label class="label is-size-7">Title</label>
<input class="input is-small" name="title" placeholder="Ship MCP browser validation for compose">
</div>
<div class="column is-5">
<label class="label is-size-7">Project</label>
<div class="select is-small is-fullwidth">
<select name="project_id">
{% for project in project_choices %}
<option value="{{ project.id }}" {% if selected_project and selected_project.id == project.id %}selected{% endif %}>{{ project.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-5">
<label class="label is-size-7">Epic (optional)</label>
<div class="select is-small is-fullwidth">
<select name="epic_id">
<option value="">No epic</option>
{% for epic in epic_choices %}
<option value="{{ epic.id }}">{{ epic.project.name }} / {{ epic.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-3">
<label class="label is-size-7">Due Date</label>
<input class="input is-small" type="date" name="due_date">
</div>
<div class="column is-4">
<label class="label is-size-7">Assignee</label>
<input class="input is-small" name="assignee_identifier" placeholder="@operator">
</div>
</div>
<button class="button is-small is-link" type="submit">Create Task</button>
</form>
</article>
<article class="box">
<h2 class="title is-6">Recent Derived Tasks</h2>
<table class="table is-fullwidth is-striped is-size-7">

View File

@@ -4,6 +4,11 @@
<div class="container tasks-settings-page">
<h1 class="title is-4">Task Automation</h1>
<p class="subtitle is-6">Project defaults flow into channel overrides. Use Quick Setup for normal operation; open Advanced Setup for full controls.</p>
<p class="help">
Related controls:
<a href="{% url 'command_routing' %}">Commands</a> and
<a href="{% url 'permission_settings' %}">Security Permissions</a>.
</p>
<div class="notification is-light">
<div class="content is-size-7">