agent-afk 5.203.0 → 5.204.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.
@@ -20,6 +20,7 @@ export declare class SessionOwner {
20
20
  readonly owned: Set<string>;
21
21
  private readonly sessions;
22
22
  private readonly info;
23
+ private readonly mcpManagers;
23
24
  private readonly turns;
24
25
  private readonly pending;
25
26
  constructor(options: SessionOwnerOptions);
@@ -0,0 +1,32 @@
1
+ import { AnthropicDirectProvider } from '../agent/providers/index.js';
2
+ import { type WiredExecutors } from '../agent/session/wire-executors.js';
3
+ import { BackgroundAgentRegistry } from '../agent/background-registry.js';
4
+ import { McpManager } from '../agent/mcp/index.js';
5
+ import { WorkspaceStore } from '../agent/workspace/index.js';
6
+ import { MemoryStore } from '../agent/memory/index.js';
7
+ import type { AgentSession } from '../agent/session/agent-session.js';
8
+ import type { AgentConfig } from '../agent/types.js';
9
+ import type { TraceWriter } from '../agent/trace/index.js';
10
+ export interface WebSessionWiring {
11
+ provider: AnthropicDirectProvider;
12
+ executors: WiredExecutors;
13
+ traceWriter: TraceWriter | undefined;
14
+ systemPrompt: string | undefined;
15
+ systemPromptSource: string | undefined;
16
+ backgroundRegistry: BackgroundAgentRegistry;
17
+ mcpManager: McpManager | undefined;
18
+ memoryStore: MemoryStore;
19
+ workspaceStore: WorkspaceStore;
20
+ drainSubagents: AgentConfig['drainSubagents'];
21
+ }
22
+ export interface WireWebSessionOptions {
23
+ model: string;
24
+ apiKey: string | undefined;
25
+ cwd: string;
26
+ rawPrompt: string | undefined;
27
+ rawPromptSource: string | undefined;
28
+ }
29
+ export declare function wireWebSession(opts: WireWebSessionOptions): Promise<WebSessionWiring>;
30
+ export interface WebSessionWiringInternal extends WebSessionWiring {
31
+ __bindSession: (s: AgentSession) => void;
32
+ }
@@ -0,0 +1,110 @@
1
+ /*
2
+ * @file affordance styles (at-file-panel.ts).
3
+ *
4
+ * All class names are prefixed `atf-` to avoid collisions with the base
5
+ * styles.css selectors. Custom properties are the same set used by styles.css
6
+ * so the affordance inherits the page theme automatically.
7
+ */
8
+
9
+ /* ── trigger button ────────────────────────────────────────────────────────── */
10
+ .atf-btn {
11
+ flex: 0 0 auto;
12
+ padding: 0 10px;
13
+ height: 38px;
14
+ background: var(--bg-sunken);
15
+ border: 1px solid var(--border);
16
+ border-radius: var(--radius);
17
+ color: var(--text-dim);
18
+ font-family: var(--mono);
19
+ font-size: 15px;
20
+ font-weight: 600;
21
+ cursor: pointer;
22
+ line-height: 1;
23
+ }
24
+
25
+ .atf-btn:hover { color: var(--text); border-color: var(--accent); }
26
+ .atf-btn--active { color: var(--accent); border-color: var(--accent); }
27
+ .atf-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
28
+
29
+ /* ── popover ────────────────────────────────────────────────────────────────── */
30
+ /*
31
+ * Invariant: the popover is positioned absolute relative to .composer-row
32
+ * (which has position:relative via the composer-row rule). bottom:100% floats
33
+ * it above the button row — same technique the slash-menu uses — so it never
34
+ * reflows the textarea.
35
+ */
36
+ .atf-popover {
37
+ position: absolute;
38
+ bottom: 100%;
39
+ right: 0;
40
+ z-index: 25;
41
+ margin-bottom: 8px;
42
+ width: 320px;
43
+ background: var(--bg-raised);
44
+ border: 1px solid var(--border);
45
+ border-radius: var(--radius);
46
+ box-shadow: 0 8px 24px rgb(0 0 0 / 45%);
47
+ padding: 10px 12px 12px;
48
+ max-height: 50vh;
49
+ overflow-y: auto;
50
+ display: flex;
51
+ flex-direction: column;
52
+ gap: 8px;
53
+ }
54
+
55
+ /* [hidden] handled by global rule — no per-element override needed. */
56
+
57
+ /* ── hint text ───────────────────────────────────────────────────────────── */
58
+ .atf-hint {
59
+ margin: 0;
60
+ font-size: 11px;
61
+ color: var(--text-faint);
62
+ font-family: var(--mono);
63
+ letter-spacing: 0.02em;
64
+ }
65
+
66
+ /* ── path input row ─────────────────────────────────────────────────────── */
67
+ .atf-input-row {
68
+ display: flex;
69
+ gap: 6px;
70
+ }
71
+
72
+ .atf-path-input {
73
+ flex: 1;
74
+ padding: 5px 8px;
75
+ background: var(--bg-sunken);
76
+ border: 1px solid var(--border);
77
+ border-radius: 6px;
78
+ color: var(--text);
79
+ font-family: var(--mono);
80
+ font-size: 13px;
81
+ min-width: 0;
82
+ }
83
+
84
+ .atf-path-input:focus { outline: none; border-color: var(--accent); }
85
+
86
+ .atf-add-btn {
87
+ flex: 0 0 auto;
88
+ padding: 5px 12px;
89
+ background: var(--accent);
90
+ color: #1a0d05;
91
+ border: none;
92
+ border-radius: 6px;
93
+ font: inherit;
94
+ font-size: 13px;
95
+ font-weight: 600;
96
+ cursor: pointer;
97
+ }
98
+
99
+ .atf-add-btn:hover { opacity: 0.88; }
100
+ .atf-add-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
101
+
102
+ /* ── inline validation error ─────────────────────────────────────────────── */
103
+ .atf-error {
104
+ margin: 0;
105
+ font-size: 11px;
106
+ color: var(--error);
107
+ font-family: var(--mono);
108
+ }
109
+
110
+ /* [hidden] handled by global rule — no per-element override needed. */
@@ -0,0 +1,130 @@
1
+ /* ── bg-jobs view container ─────────────────────────────────────────────── */
2
+
3
+ .bgjob-view { flex: 1; display: flex; flex-direction: column; overflow-y: auto; padding: 24px; }
4
+
5
+ /* ── bg-jobs panel ────────────────────────────────────────────────────────── */
6
+
7
+ .bgjobs-title { margin: 0 0 16px; font-size: 18px; font-weight: 600; color: var(--text); }
8
+
9
+ .bgjobs-panel {
10
+ max-width: 900px; width: 100%;
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: 4px;
14
+ padding: 8px 0;
15
+ }
16
+
17
+ /* ── empty state ─────────────────────────────────────────────────────────── */
18
+
19
+ .bgjobs-empty {
20
+ padding: 24px 16px;
21
+ text-align: center;
22
+ font-size: 13px;
23
+ color: var(--text-faint);
24
+ }
25
+
26
+ /* ── job row ─────────────────────────────────────────────────────────────── */
27
+
28
+ .bgjob-row {
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 10px;
32
+ padding: 8px 12px;
33
+ border-radius: 6px;
34
+ background: var(--bg-raised);
35
+ border: 1px solid var(--border);
36
+ min-width: 0;
37
+ }
38
+
39
+ /* ── status badge ────────────────────────────────────────────────────────── */
40
+
41
+ .bgjob-badge {
42
+ flex: 0 0 auto;
43
+ font-family: var(--mono);
44
+ font-size: 10px;
45
+ font-weight: 600;
46
+ text-transform: uppercase;
47
+ letter-spacing: 0.06em;
48
+ padding: 2px 6px;
49
+ border-radius: 4px;
50
+ border: 1px solid transparent;
51
+ }
52
+
53
+ .bgjob-badge--running {
54
+ color: var(--accent);
55
+ border-color: var(--accent);
56
+ background: color-mix(in srgb, var(--accent) 10%, transparent);
57
+ }
58
+
59
+ .bgjob-badge--completed {
60
+ color: var(--success);
61
+ border-color: var(--success);
62
+ background: color-mix(in srgb, var(--success) 10%, transparent);
63
+ }
64
+
65
+ .bgjob-badge--failed {
66
+ color: var(--error);
67
+ border-color: var(--error);
68
+ background: color-mix(in srgb, var(--error) 10%, transparent);
69
+ }
70
+
71
+ .bgjob-badge--cancelled {
72
+ color: var(--text-dim);
73
+ border-color: var(--border);
74
+ background: transparent;
75
+ }
76
+
77
+ /* ── pulse dot for running jobs ─────────────────────────────────────────── */
78
+
79
+ .bgjob-pulse {
80
+ flex: 0 0 auto;
81
+ width: 7px;
82
+ height: 7px;
83
+ border-radius: 50%;
84
+ background: var(--accent);
85
+ animation: bgjob-pulse 1.6s ease-in-out infinite;
86
+ }
87
+
88
+ @keyframes bgjob-pulse {
89
+ 0%, 100% { opacity: 1; transform: scale(1); }
90
+ 50% { opacity: 0.35; transform: scale(0.75); }
91
+ }
92
+
93
+ /* ── label + meta ────────────────────────────────────────────────────────── */
94
+
95
+ .bgjob-body {
96
+ flex: 1 1 0;
97
+ min-width: 0;
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 2px;
101
+ }
102
+
103
+ .bgjob-label {
104
+ font-size: 12px;
105
+ color: var(--text);
106
+ white-space: nowrap;
107
+ overflow: hidden;
108
+ text-overflow: ellipsis;
109
+ }
110
+
111
+ .bgjob-meta {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 8px;
115
+ font-family: var(--mono);
116
+ font-size: 10px;
117
+ color: var(--text-faint);
118
+ }
119
+
120
+ .bgjob-model {
121
+ white-space: nowrap;
122
+ overflow: hidden;
123
+ text-overflow: ellipsis;
124
+ max-width: 140px;
125
+ }
126
+
127
+ .bgjob-duration {
128
+ white-space: nowrap;
129
+ flex-shrink: 0;
130
+ }
@@ -0,0 +1,168 @@
1
+ /* ── diff-viewer.css ────────────────────────────────────────────────────────
2
+ * Styles for the enhanced diff viewer (diff-viewer.ts).
3
+ * All classes are prefixed `dv-` to avoid collisions with the legacy
4
+ * `.diff-add / .diff-del / .diff-ctx / .diff-hunk` classes in styles.css.
5
+ *
6
+ * Relies on custom properties defined in styles.css:
7
+ * --mono, --success, --error, --text-dim, --text-faint,
8
+ * --bg-sunken, --accent, --border, --radius
9
+ * ────────────────────────────────────────────────────────────────────────── */
10
+
11
+ .dv-root {
12
+ font-family: var(--mono);
13
+ font-size: 12px;
14
+ line-height: 1.5;
15
+ border: 1px solid var(--border);
16
+ border-radius: var(--radius);
17
+ overflow: hidden;
18
+ }
19
+
20
+ /* File header ──────────────────────────────────────────────────────────── */
21
+
22
+ .dv-file-header {
23
+ display: flex;
24
+ align-items: center;
25
+ gap: 6px;
26
+ padding: 5px 10px;
27
+ background: var(--bg-sunken);
28
+ border-bottom: 1px solid var(--border);
29
+ font-size: 11px;
30
+ color: var(--text-dim);
31
+ }
32
+
33
+ .dv-file-icon { flex: 0 0 auto; }
34
+
35
+ .dv-file-name {
36
+ color: var(--text);
37
+ overflow: hidden;
38
+ text-overflow: ellipsis;
39
+ white-space: nowrap;
40
+ }
41
+
42
+ /* Empty state ──────────────────────────────────────────────────────────── */
43
+
44
+ .dv-empty {
45
+ padding: 8px 12px;
46
+ color: var(--text-faint);
47
+ font-style: italic;
48
+ }
49
+
50
+ /* Hunk container (<details>) ───────────────────────────────────────────── */
51
+
52
+ .dv-hunk {
53
+ border-bottom: 1px solid var(--border);
54
+ }
55
+
56
+ .dv-hunk:last-child { border-bottom: 0; }
57
+
58
+ /* Hunk header (<summary>) ──────────────────────────────────────────────── */
59
+
60
+ .dv-hunk-header {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 6px;
64
+ padding: 3px 8px;
65
+ background: color-mix(in srgb, var(--accent) 6%, var(--bg-sunken));
66
+ border-bottom: 1px solid var(--border);
67
+ cursor: pointer;
68
+ list-style: none;
69
+ user-select: none;
70
+ color: var(--text-dim);
71
+ font-size: 11px;
72
+ }
73
+
74
+ /* Remove default UA marker across browsers */
75
+ .dv-hunk-header::-webkit-details-marker { display: none; }
76
+
77
+ .dv-chevron {
78
+ flex: 0 0 auto;
79
+ font-size: 9px;
80
+ color: var(--text-faint);
81
+ transition: transform 0.15s ease;
82
+ /* Invariant: chevron rotates 90° when the <details> is open.
83
+ The selector targets .dv-hunk[open] > summary > .dv-chevron so the
84
+ transition is driven by the details[open] attribute, not JS state. */
85
+ }
86
+
87
+ details.dv-hunk[open] > .dv-hunk-header > .dv-chevron {
88
+ transform: rotate(90deg);
89
+ }
90
+
91
+ .dv-hunk-range {
92
+ flex: 1;
93
+ color: var(--accent);
94
+ opacity: 0.8;
95
+ overflow: hidden;
96
+ text-overflow: ellipsis;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ .dv-hunk-stats {
101
+ flex: 0 0 auto;
102
+ color: var(--text-faint);
103
+ font-size: 10px;
104
+ letter-spacing: 0.04em;
105
+ }
106
+
107
+ /* Hunk body ────────────────────────────────────────────────────────────── */
108
+
109
+ .dv-hunk-body {
110
+ overflow-x: auto;
111
+ }
112
+
113
+ /* Line rows ────────────────────────────────────────────────────────────── */
114
+
115
+ .dv-line {
116
+ display: flex;
117
+ align-items: baseline;
118
+ min-width: 0;
119
+ white-space: pre;
120
+ }
121
+
122
+ .dv-line-add {
123
+ background: color-mix(in srgb, var(--success) 8%, transparent);
124
+ color: var(--success);
125
+ }
126
+
127
+ .dv-line-del {
128
+ background: color-mix(in srgb, var(--error) 8%, transparent);
129
+ color: var(--error);
130
+ }
131
+
132
+ .dv-line-ctx {
133
+ color: var(--text-dim);
134
+ }
135
+
136
+ /* Gutter (line numbers) ────────────────────────────────────────────────── */
137
+
138
+ .dv-gutter {
139
+ flex: 0 0 3.5ch;
140
+ text-align: right;
141
+ padding: 0 6px 0 4px;
142
+ color: var(--text-faint);
143
+ user-select: none;
144
+ border-right: 1px solid var(--border);
145
+ /* Gutter numbers use same font but smaller — they frame, not compete. */
146
+ font-size: 10px;
147
+ line-height: 1.7;
148
+ }
149
+
150
+ /* Sigil (+ / - / space) ────────────────────────────────────────────────── */
151
+
152
+ .dv-sigil {
153
+ flex: 0 0 1.4ch;
154
+ text-align: center;
155
+ user-select: none;
156
+ font-weight: 600;
157
+ }
158
+
159
+ .dv-line-ctx .dv-sigil { opacity: 0; }
160
+
161
+ /* Content ──────────────────────────────────────────────────────────────── */
162
+
163
+ .dv-content {
164
+ flex: 1;
165
+ padding: 0 8px;
166
+ /* No overflow here — horizontal scroll lives on .dv-hunk-body so long
167
+ lines push it wide enough to trigger the scrollbar. */
168
+ }
@@ -0,0 +1,146 @@
1
+ /* ── memory view ─────────────────────────────────────────────────────────── */
2
+
3
+ .mem-view { flex: 1; display: flex; flex-direction: column; overflow-y: auto; padding: 24px; }
4
+ .mem-panel { display: flex; flex-direction: column; flex: 1; }
5
+
6
+ .mem-inner { max-width: 900px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }
7
+
8
+ /* ── header ──────────────────────────────────────────────────────────────── */
9
+ .mem-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--text); }
10
+
11
+ /* ── hot memory section ──────────────────────────────────────────────────── */
12
+ .mem-hot {
13
+ background: var(--bg-raised); border: 1px solid var(--border);
14
+ border-radius: var(--radius); padding: 16px;
15
+ }
16
+ .mem-hot-header {
17
+ display: flex; align-items: center; justify-content: space-between;
18
+ margin-bottom: 10px; gap: 12px;
19
+ }
20
+ .mem-hot-title {
21
+ font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
22
+ color: var(--text-dim); font-weight: 600;
23
+ }
24
+ .mem-hot-meta { display: flex; align-items: center; gap: 10px; }
25
+ .mem-hot-pct {
26
+ font-family: var(--mono); font-size: 11px; color: var(--text-dim);
27
+ }
28
+ .mem-hot-truncated {
29
+ font-size: 10px; color: var(--warning); padding: 1px 6px;
30
+ border: 1px solid color-mix(in srgb, var(--warning) 40%, transparent);
31
+ border-radius: 4px; text-transform: uppercase; letter-spacing: 0.05em;
32
+ }
33
+
34
+ /* Usage meter bar */
35
+ .mem-usage-bar {
36
+ height: 3px; background: var(--bg-sunken); border-radius: 2px; margin-bottom: 10px;
37
+ }
38
+ .mem-usage-fill {
39
+ height: 100%; border-radius: 2px; background: var(--accent);
40
+ transition: width 0.3s ease;
41
+ }
42
+ .mem-usage-fill.is-warn { background: var(--warning); }
43
+ .mem-usage-fill.is-full { background: var(--error); }
44
+
45
+ .mem-hot-pre {
46
+ font-family: var(--mono); font-size: 12px; color: var(--text-dim);
47
+ background: var(--bg-sunken); border: 1px solid var(--border);
48
+ border-radius: 6px; padding: 12px; margin: 0;
49
+ white-space: pre-wrap; word-break: break-word;
50
+ max-height: 240px; overflow-y: auto;
51
+ }
52
+ .mem-hot-empty {
53
+ font-size: 13px; color: var(--text-faint); font-style: italic;
54
+ padding: 8px 0;
55
+ }
56
+
57
+ /* ── search bar ──────────────────────────────────────────────────────────── */
58
+ .mem-search-row {
59
+ display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
60
+ }
61
+ .mem-search-input {
62
+ flex: 1; min-width: 180px; padding: 8px 12px;
63
+ background: var(--bg-raised); border: 1px solid var(--border);
64
+ border-radius: 6px; color: var(--text); font: inherit; font-size: 13px;
65
+ }
66
+ .mem-search-input:focus { outline: none; border-color: var(--accent); }
67
+ .mem-search-input::placeholder { color: var(--text-faint); }
68
+ .mem-cat-select {
69
+ padding: 8px 10px; background: var(--bg-raised); border: 1px solid var(--border);
70
+ border-radius: 6px; color: var(--text); font: inherit; font-size: 13px;
71
+ cursor: pointer;
72
+ }
73
+ .mem-cat-select:focus { outline: none; border-color: var(--accent); }
74
+ .mem-search-btn {
75
+ font: inherit; font-size: 13px; font-weight: 600;
76
+ color: #1a0d05; background: var(--accent);
77
+ border: none; border-radius: 6px; padding: 8px 18px; cursor: pointer;
78
+ white-space: nowrap; transition: opacity 0.15s ease;
79
+ }
80
+ .mem-search-btn:hover:not(:disabled) { opacity: 0.88; }
81
+ .mem-search-btn:disabled { opacity: 0.5; cursor: default; }
82
+
83
+ /* ── result list ─────────────────────────────────────────────────────────── */
84
+ .mem-results { display: flex; flex-direction: column; gap: 8px; }
85
+
86
+ .mem-empty {
87
+ text-align: center; padding: 40px 20px; color: var(--text-dim);
88
+ }
89
+ .mem-empty-icon { font-size: 32px; margin-bottom: 10px; }
90
+ .mem-empty-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
91
+ .mem-empty-sub { font-size: 13px; }
92
+
93
+ .mem-loading { padding: 20px; text-align: center; color: var(--text-dim); font-size: 13px; }
94
+ .mem-error { padding: 12px; background: color-mix(in srgb, var(--error) 10%, transparent);
95
+ border: 1px solid color-mix(in srgb, var(--error) 30%, transparent);
96
+ border-radius: 6px; color: var(--error); font-size: 13px; }
97
+
98
+ /* ── result card ─────────────────────────────────────────────────────────── */
99
+ .mem-card {
100
+ background: var(--bg-raised); border: 1px solid var(--border);
101
+ border-radius: var(--radius); padding: 12px 14px;
102
+ transition: border-color 0.15s ease;
103
+ }
104
+ .mem-card:hover { border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
105
+
106
+ .mem-card-top {
107
+ display: flex; align-items: center; gap: 7px; margin-bottom: 8px; flex-wrap: wrap;
108
+ }
109
+
110
+ /* Type badge */
111
+ .mem-badge-type {
112
+ font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em;
113
+ padding: 2px 7px; border-radius: 4px;
114
+ }
115
+ .mem-badge-fact {
116
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
117
+ color: var(--accent);
118
+ border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
119
+ }
120
+ .mem-badge-procedure {
121
+ background: color-mix(in srgb, var(--purple) 12%, transparent);
122
+ color: var(--purple);
123
+ border: 1px solid color-mix(in srgb, var(--purple) 30%, transparent);
124
+ }
125
+
126
+ /* Category badge */
127
+ .mem-badge-cat {
128
+ font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
129
+ padding: 2px 6px; border-radius: 4px;
130
+ background: var(--bg-sunken); border: 1px solid var(--border);
131
+ color: var(--text-faint);
132
+ }
133
+ .mem-badge-preference { color: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 30%, transparent); }
134
+ .mem-badge-convention { color: var(--mint); border-color: color-mix(in srgb, var(--mint) 30%, transparent); }
135
+ .mem-badge-decision { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
136
+ .mem-badge-learning { color: var(--lavender); border-color: color-mix(in srgb, var(--lavender) 30%, transparent); }
137
+
138
+ .mem-card-date {
139
+ margin-left: auto; font-size: 11px; color: var(--text-faint); white-space: nowrap;
140
+ }
141
+
142
+ /* Content preview */
143
+ .mem-card-content {
144
+ font-size: 13px; color: var(--text-dim); line-height: 1.5;
145
+ white-space: pre-wrap; word-break: break-word;
146
+ }