@sigil0/looking-glass 0.1.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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +572 -0
  3. package/dist/agents/coordinator.d.ts +21 -0
  4. package/dist/agents/coordinator.d.ts.map +1 -0
  5. package/dist/agents/coordinator.js +171 -0
  6. package/dist/agents/coordinator.js.map +1 -0
  7. package/dist/app.d.ts +44 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +215 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +419 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +4 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +132 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/engine/context.d.ts +6 -0
  20. package/dist/engine/context.d.ts.map +1 -0
  21. package/dist/engine/context.js +65 -0
  22. package/dist/engine/context.js.map +1 -0
  23. package/dist/engine/engine.d.ts +74 -0
  24. package/dist/engine/engine.d.ts.map +1 -0
  25. package/dist/engine/engine.js +573 -0
  26. package/dist/engine/engine.js.map +1 -0
  27. package/dist/engine/types.d.ts +35 -0
  28. package/dist/engine/types.d.ts.map +1 -0
  29. package/dist/engine/types.js +2 -0
  30. package/dist/engine/types.js.map +1 -0
  31. package/dist/instructions.d.ts +8 -0
  32. package/dist/instructions.d.ts.map +1 -0
  33. package/dist/instructions.js +60 -0
  34. package/dist/instructions.js.map +1 -0
  35. package/dist/model/codex-lb.d.ts +141 -0
  36. package/dist/model/codex-lb.d.ts.map +1 -0
  37. package/dist/model/codex-lb.js +471 -0
  38. package/dist/model/codex-lb.js.map +1 -0
  39. package/dist/paths.d.ts +7 -0
  40. package/dist/paths.d.ts.map +1 -0
  41. package/dist/paths.js +41 -0
  42. package/dist/paths.js.map +1 -0
  43. package/dist/scheduler/daemon.d.ts +40 -0
  44. package/dist/scheduler/daemon.d.ts.map +1 -0
  45. package/dist/scheduler/daemon.js +189 -0
  46. package/dist/scheduler/daemon.js.map +1 -0
  47. package/dist/scheduler/index.d.ts +8 -0
  48. package/dist/scheduler/index.d.ts.map +1 -0
  49. package/dist/scheduler/index.js +6 -0
  50. package/dist/scheduler/index.js.map +1 -0
  51. package/dist/scheduler/runner.d.ts +18 -0
  52. package/dist/scheduler/runner.d.ts.map +1 -0
  53. package/dist/scheduler/runner.js +173 -0
  54. package/dist/scheduler/runner.js.map +1 -0
  55. package/dist/scheduler/schedule.d.ts +7 -0
  56. package/dist/scheduler/schedule.d.ts.map +1 -0
  57. package/dist/scheduler/schedule.js +94 -0
  58. package/dist/scheduler/schedule.js.map +1 -0
  59. package/dist/scheduler/store.d.ts +55 -0
  60. package/dist/scheduler/store.d.ts.map +1 -0
  61. package/dist/scheduler/store.js +1203 -0
  62. package/dist/scheduler/store.js.map +1 -0
  63. package/dist/scheduler/systemd.d.ts +7 -0
  64. package/dist/scheduler/systemd.d.ts.map +1 -0
  65. package/dist/scheduler/systemd.js +97 -0
  66. package/dist/scheduler/systemd.js.map +1 -0
  67. package/dist/scheduler/types.d.ts +145 -0
  68. package/dist/scheduler/types.d.ts.map +1 -0
  69. package/dist/scheduler/types.js +7 -0
  70. package/dist/scheduler/types.js.map +1 -0
  71. package/dist/security.d.ts +6 -0
  72. package/dist/security.d.ts.map +1 -0
  73. package/dist/security.js +27 -0
  74. package/dist/security.js.map +1 -0
  75. package/dist/storage/artifact-store.d.ts +19 -0
  76. package/dist/storage/artifact-store.d.ts.map +1 -0
  77. package/dist/storage/artifact-store.js +47 -0
  78. package/dist/storage/artifact-store.js.map +1 -0
  79. package/dist/storage/database.d.ts +5 -0
  80. package/dist/storage/database.d.ts.map +1 -0
  81. package/dist/storage/database.js +395 -0
  82. package/dist/storage/database.js.map +1 -0
  83. package/dist/storage/session-store.d.ts +114 -0
  84. package/dist/storage/session-store.d.ts.map +1 -0
  85. package/dist/storage/session-store.js +731 -0
  86. package/dist/storage/session-store.js.map +1 -0
  87. package/dist/tools/agents.d.ts +14 -0
  88. package/dist/tools/agents.d.ts.map +1 -0
  89. package/dist/tools/agents.js +35 -0
  90. package/dist/tools/agents.js.map +1 -0
  91. package/dist/tools/apply-patch.d.ts +7 -0
  92. package/dist/tools/apply-patch.d.ts.map +1 -0
  93. package/dist/tools/apply-patch.js +429 -0
  94. package/dist/tools/apply-patch.js.map +1 -0
  95. package/dist/tools/ask.d.ts +8 -0
  96. package/dist/tools/ask.d.ts.map +1 -0
  97. package/dist/tools/ask.js +27 -0
  98. package/dist/tools/ask.js.map +1 -0
  99. package/dist/tools/bash.d.ts +9 -0
  100. package/dist/tools/bash.d.ts.map +1 -0
  101. package/dist/tools/bash.js +98 -0
  102. package/dist/tools/bash.js.map +1 -0
  103. package/dist/tools/index.d.ts +9 -0
  104. package/dist/tools/index.d.ts.map +1 -0
  105. package/dist/tools/index.js +34 -0
  106. package/dist/tools/index.js.map +1 -0
  107. package/dist/tools/paths.d.ts +3 -0
  108. package/dist/tools/paths.d.ts.map +1 -0
  109. package/dist/tools/paths.js +34 -0
  110. package/dist/tools/paths.js.map +1 -0
  111. package/dist/tools/process.d.ts +21 -0
  112. package/dist/tools/process.d.ts.map +1 -0
  113. package/dist/tools/process.js +104 -0
  114. package/dist/tools/process.js.map +1 -0
  115. package/dist/tools/read.d.ts +9 -0
  116. package/dist/tools/read.d.ts.map +1 -0
  117. package/dist/tools/read.js +95 -0
  118. package/dist/tools/read.js.map +1 -0
  119. package/dist/tools/registry.d.ts +19 -0
  120. package/dist/tools/registry.d.ts.map +1 -0
  121. package/dist/tools/registry.js +188 -0
  122. package/dist/tools/registry.js.map +1 -0
  123. package/dist/tools/safety.d.ts +9 -0
  124. package/dist/tools/safety.d.ts.map +1 -0
  125. package/dist/tools/safety.js +199 -0
  126. package/dist/tools/safety.js.map +1 -0
  127. package/dist/tools/schedule.d.ts +4 -0
  128. package/dist/tools/schedule.d.ts.map +1 -0
  129. package/dist/tools/schedule.js +191 -0
  130. package/dist/tools/schedule.js.map +1 -0
  131. package/dist/tools/search.d.ts +16 -0
  132. package/dist/tools/search.d.ts.map +1 -0
  133. package/dist/tools/search.js +75 -0
  134. package/dist/tools/search.js.map +1 -0
  135. package/dist/tools/types.d.ts +54 -0
  136. package/dist/tools/types.d.ts.map +1 -0
  137. package/dist/tools/types.js +10 -0
  138. package/dist/tools/types.js.map +1 -0
  139. package/dist/types.d.ts +90 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +2 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/ui/stdio.d.ts +5 -0
  144. package/dist/ui/stdio.d.ts.map +1 -0
  145. package/dist/ui/stdio.js +65 -0
  146. package/dist/ui/stdio.js.map +1 -0
  147. package/dist/ui/tui.d.ts +93 -0
  148. package/dist/ui/tui.d.ts.map +1 -0
  149. package/dist/ui/tui.js +2246 -0
  150. package/dist/ui/tui.js.map +1 -0
  151. package/package.json +53 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 S1gil0
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,572 @@
1
+ # Looking Glass
2
+
3
+ ![Looking Glass title graphic](./looking-glass-title.svg)
4
+
5
+ Looking Glass is a local AI coding CLI that turns a terminal workspace into a durable, context-aware working session. It connects to an OpenAI-compatible gateway such as LM Studio, gives the model workspace tools, stores the conversation and tool history in SQLite, and can wake the same session later to continue a task automatically.
6
+
7
+ The important idea is **a session is more than a chat window**. A session remembers:
8
+
9
+ - The conversation, tool calls, response continuity, and compaction checkpoints.
10
+ - The workspace where the work happened.
11
+ - The selected provider, model, reasoning effort, permissions, agent settings, and persistence state.
12
+ - Schedules attached to that session.
13
+ - Durable tool output artifacts and scheduler inbox records.
14
+
15
+ That makes it possible to start a task in the morning, schedule the session to inspect the result in the afternoon, and have the next model turn resume with the same context and files instead of starting from a blank prompt.
16
+
17
+ Looking Glass is designed for one local operator. It is not a hosted service, multi-user system, or replacement for operating-system isolation.
18
+
19
+ ## Why Use It
20
+
21
+ Looking Glass combines a coding assistant, durable project memory, and a local automation loop:
22
+
23
+ - **Interactive terminal chat** with scrollback, copy selection, approvals, and live tool progress.
24
+ - **One-shot CLI prompts** for scripts, quick questions, CI-adjacent tasks, and shell pipelines.
25
+ - **Durable sessions** that preserve context across restarts and explicit resumes.
26
+ - **Workspace-aware tools** for reading, searching, patching, and running bounded Bash commands.
27
+ - **Scheduled session prompts** that run a future AI turn in an existing persistent session.
28
+ - **Deterministic schedules** for reminders and exact shell commands.
29
+ - **Concurrent agents** for independent discovery, implementation, and review tasks.
30
+ - **Context recovery and compaction** when a provider loses response continuity or the context grows large.
31
+ - **SQLite-backed state and artifacts** instead of ephemeral terminal-only history.
32
+ - **Provider selection** across configured OpenAI-compatible gateways.
33
+ - **Approval modes** that let you choose review, coding, or fully noninteractive unrestricted operation.
34
+
35
+ ## Requirements
36
+
37
+ - Linux
38
+ - Node.js 22 or newer
39
+ - npm
40
+ - `ripgrep` (`rg`)
41
+ - A running LM Studio or other OpenAI-compatible server exposing a Responses API
42
+
43
+ For a local LM Studio setup, the gateway URL is:
44
+
45
+ ```text
46
+ http://127.0.0.1:1234/v1
47
+ ```
48
+
49
+ ## Install from npm
50
+
51
+ On Linux with Node.js 22 or newer:
52
+
53
+ ```bash
54
+ npm install --global @sigil0/looking-glass
55
+ glass --version
56
+ ```
57
+
58
+ The package is Linux-only for now. Windows users can run it through WSL2.
59
+
60
+ ## Install From Source
61
+
62
+ The package is not published to npm. Install it from the public source repository:
63
+
64
+ ```bash
65
+ git clone https://github.com/S1gil0/lookingglass.git
66
+ cd lookingglass
67
+ npm ci
68
+ npm run build
69
+ npm link
70
+ glass --version
71
+ ```
72
+
73
+ You can run directly from TypeScript during development with `npm run dev`, but the installed `glass` command and scheduler service use the compiled `dist/` output.
74
+
75
+ ## Configure a Gateway
76
+
77
+ Looking Glass expects an OpenAI-compatible Responses API and `/v1/models`. The optional API key is read from the environment variable named by `gateway.apiKeyEnv`:
78
+
79
+ ```bash
80
+ export LM_STUDIO_API_KEY=replace-with-your-token
81
+ ```
82
+
83
+ Configuration is loaded in this order:
84
+
85
+ ```text
86
+ ~/.config/looking-glass/config.jsonc
87
+ ~/.config/looking-glass/config.json
88
+ <workspace>/.looking-glass.jsonc
89
+ <workspace>/.looking-glass.json
90
+ ```
91
+
92
+ Set `LOOKING_GLASS_CONFIG` to use a different explicit JSON or JSONC file. Workspace settings are applied after global settings, so a project can select its own model, gateway, instructions, or safety defaults.
93
+
94
+ Example configuration:
95
+
96
+ ```jsonc
97
+ {
98
+ "gateway": {
99
+ "provider": "lm-studio",
100
+ "baseURL": "http://127.0.0.1:1234/v1",
101
+ "apiKeyEnv": "LM_STUDIO_API_KEY",
102
+ "timeoutMs": 600000
103
+ },
104
+ "model": "example-model",
105
+ "reasoningEffort": "medium",
106
+ "verbosity": "low",
107
+ "fast": false,
108
+ "tools": {
109
+ "approval": "code",
110
+ "shellTimeoutMs": 120000,
111
+ "maxOutputBytes": 65536,
112
+ "maxReadLines": 2000,
113
+ "maxToolRounds": 1000
114
+ },
115
+ "scheduler": {
116
+ "timezone": "UTC",
117
+ "pollIntervalMs": 1000,
118
+ "leaseMs": 20000,
119
+ "maxConcurrentCommands": 2,
120
+ "commandStartGraceMs": 60000,
121
+ "commandTimeoutMs": 600000,
122
+ "commandOutputBytes": 65536
123
+ }
124
+ }
125
+ ```
126
+
127
+ The default approval mode is `code`.
128
+
129
+ ### LM Studio and OpenAI-Compatible Gateways
130
+
131
+ LM Studio is one local option, but Looking Glass works with any gateway that
132
+ exposes the OpenAI-compatible Responses API and `/v1/models`. This includes
133
+ `codex-lb` and compatible deployments of vLLM, LiteLLM, LocalAI, llama.cpp,
134
+ Ollama, or hosted OpenAI-compatible endpoints. The exact feature set depends
135
+ on the gateway's support for Responses API streaming, tools, and model
136
+ metadata.
137
+
138
+ If authentication is disabled, omit `apiKeyEnv` from the gateway configuration:
139
+
140
+ ```bash
141
+ export LM_STUDIO_API_KEY=replace-with-your-token
142
+ ```
143
+
144
+ ```jsonc
145
+ {
146
+ "gateway": {
147
+ "provider": "lm-studio",
148
+ "baseURL": "http://127.0.0.1:1234/v1",
149
+ "apiKeyEnv": "LM_STUDIO_API_KEY"
150
+ }
151
+ }
152
+ ```
153
+
154
+ Inspect the configured model catalog and gateway health:
155
+
156
+ ```bash
157
+ glass models
158
+ ```
159
+
160
+ Use a provider-prefixed model ID to make an explicit provider selection:
161
+
162
+ ```text
163
+ /model lm-studio:example-model
164
+ ```
165
+
166
+ Changing provider or model rotates remote continuity and cache identity, then replays the durable local session history. Provider affinity is retained, so a provider does not change silently.
167
+
168
+ ## CLI At A Glance
169
+
170
+ Run `glass help` for the built-in synopsis:
171
+
172
+ ```text
173
+ glass Start the interactive chat
174
+ glass run [--yes] [--session ID] PROMPT
175
+ glass models List provider, model, context, and display name
176
+ glass sessions List durable interactive sessions
177
+ glass sessions persist ID on|off
178
+ glass config Print paths, instruction files, and effective config
179
+ glass doctor Check SQLite, ripgrep, providers, and scheduler status
180
+ glass cron ... Create and manage reminders, commands, and session prompts
181
+ ```
182
+
183
+ ### Start an Interactive Session
184
+
185
+ Run `glass` from the workspace you want the model to work in:
186
+
187
+ ```bash
188
+ cd ~/src/my-project
189
+ glass
190
+ ```
191
+
192
+ Bare `glass` starts a fresh session. It appears in session history only after its first message; exiting or switching away before then discards the empty draft. The top metadata line shows the active model, reasoning effort, context usage, agent state, approval mode, persistence state, and session title. The transcript and tool history are saved as you work.
193
+
194
+ ### Run One Prompt
195
+
196
+ Use `glass run` when you want a single prompt from a script or a regular shell:
197
+
198
+ ```bash
199
+ glass run "Inspect the project and summarize its current state"
200
+ glass run "Run the tests and explain any failures"
201
+ ```
202
+
203
+ Use `--session` to continue an existing session instead of creating a new one:
204
+
205
+ ```bash
206
+ glass run --session SESSION_ID "Continue the deployment investigation"
207
+ ```
208
+
209
+ `glass run --yes` automatically approves normal interactive approvals for the one-shot process, but does not approve persistent or critical actions. For fully noninteractive work, use a session whose durable approval mode is `unrestricted`.
210
+
211
+ ### Inspect the Local Installation
212
+
213
+ ```bash
214
+ glass --help
215
+ glass --version
216
+ glass models
217
+ glass sessions
218
+ glass config
219
+ glass doctor
220
+ ```
221
+
222
+ `glass config` is useful when a session is using an unexpected model or gateway. It prints the workspace, state database, loaded instruction files, truncation status, and effective configuration.
223
+
224
+ ## Sessions: Durable Project Memory
225
+
226
+ A session is a durable work thread scoped to a workspace. It is the unit that connects conversation context, files, model settings, permissions, and schedules.
227
+
228
+ ### Start, Resume, and Switch
229
+
230
+ ```bash
231
+ glass # New interactive session in the current workspace
232
+ glass chat --session ID # Resume an interactive session
233
+ glass run --session ID "..." # Continue it with one prompt
234
+ ```
235
+
236
+ Inside the TUI:
237
+
238
+ ```text
239
+ /new
240
+ /sessions
241
+ /sessions SESSION_ID
242
+ ```
243
+
244
+ Use `/new` for a separate task, even in the same folder. This keeps unrelated context from contaminating one another. Use `/sessions` when you want to browse titles, models, approval modes, persistence state, schedule counts, and last activity.
245
+
246
+ ### What Persists
247
+
248
+ Looking Glass stores session events and tool state in SQLite. Depending on the provider, it also stores local replay material or response continuity identifiers. Context compaction creates durable checkpoints instead of deleting the session's identity.
249
+
250
+ The workspace is part of the session's operating context. Files are not copied into the database: the session continues to work against the same workspace on disk. If you schedule a prompt for a session, the scheduler opens that session in its workspace and sends the next model turn with the session's durable history.
251
+
252
+ This means a scheduled session can naturally follow a task such as:
253
+
254
+ 1. Ask the model to scaffold a service.
255
+ 2. Leave the workspace while tests or a deployment run.
256
+ 3. Schedule the same session to inspect the result.
257
+ 4. Let the scheduled turn read the files, see the prior conversation, run tools, and report or fix the next issue.
258
+
259
+ The model does not magically remember external changes that were never written to the workspace or session events. A scheduled prompt should explicitly ask it to inspect current files, logs, test results, or other durable inputs.
260
+
261
+ ### Rename and Manage a Session
262
+
263
+ Use `/session` for the session menu. It can rename the session, manage persistence, inspect schedules, and review or revoke remembered approvals. Session deletion is permanent for the transcript, checkpoints, tool records, attached schedules, scheduler occurrences, inbox records, and approvals. Detached artifact files are retained.
264
+
265
+ ## TUI Commands
266
+
267
+ Enter slash commands inside `glass`:
268
+
269
+ | Command | Purpose |
270
+ | --- | --- |
271
+ | `/new` | Create and switch to a new session |
272
+ | `/sessions [ID]` | Browse sessions or switch directly to an ID |
273
+ | `/session` | Open session management, rename, persistence, schedules, or approvals |
274
+ | `/persist [on\|off]` | Enable or disable persistence for this session |
275
+ | `/model [ID]` | Select a primary model; without an ID, open the model picker |
276
+ | `/reasoning [effort]` | Select primary model reasoning effort |
277
+ | `/agents [on\|off]` | Enable or disable delegation for this session |
278
+ | `/agentmodel [ID]` | Select the model used by leaf agents |
279
+ | `/agentreasoning [effort]` | Select leaf-agent reasoning effort |
280
+ | `/thinking [on\|off]` | Show or hide model-provided reasoning summaries |
281
+ | `/fast [on\|off]` | Toggle fast service when supported |
282
+ | `/compact` | Compact the current conversation context |
283
+ | `/permissions [review\|code\|unrestricted]` | Change durable approval mode |
284
+ | `/schedule ...` | Schedule an AI turn in this session |
285
+ | `/cron [session]` | Browse, run, pause, resume, resolve, or delete schedules |
286
+ | `/inbox` | Show unread scheduler records and mark them read |
287
+ | `/exit` | Exit the TUI |
288
+
289
+ The transcript supports mouse-wheel scrolling, `PageUp`, and `PageDown`. Dragging across text selects and copies it through OSC52 with a native clipboard fallback. `Ctrl+C` cancels the active turn or exits when no turn is running.
290
+
291
+ ## The Main Automation Workflow
292
+
293
+ Scheduled session prompts are the feature to use when you want Looking Glass to continue a project by itself. A scheduled prompt is not a detached new chat. It is a future turn of an existing session.
294
+
295
+ ### Schedule From Inside the Session
296
+
297
+ First make the session persistent:
298
+
299
+ ```text
300
+ /persist on
301
+ ```
302
+
303
+ Then schedule a one-shot follow-up:
304
+
305
+ ```text
306
+ /schedule once 2026-07-20T12:00:00Z Inspect the current test results and fix any failures
307
+ ```
308
+
309
+ Or schedule a recurring review using a five-field cron expression:
310
+
311
+ ```text
312
+ /schedule cron "0 9 * * 1-5" Review project health, run the tests, and report anything requiring operator action
313
+ ```
314
+
315
+ If you use `/schedule` before persistence is enabled, the TUI offers to enable it. Scheduled session prompts inherit the current session's workspace, conversation, model, agent settings, approval mode, and durable state.
316
+
317
+ ### Schedule From the CLI
318
+
319
+ Use `glass cron prompt` with an existing session:
320
+
321
+ ```bash
322
+ glass cron prompt --once 2026-07-20T12:00:00Z --session SESSION_ID "Inspect the current test results and fix any failures"
323
+ ```
324
+
325
+ Recurring prompt:
326
+
327
+ ```bash
328
+ glass cron prompt --cron "0 9 * * 1-5" --timezone UTC --session SESSION_ID "Review project health and report anything requiring operator action"
329
+ ```
330
+
331
+ The target session must be persistent. Enable it from the TUI with `/persist on` or from the CLI:
332
+
333
+ ```bash
334
+ glass sessions persist SESSION_ID on
335
+ ```
336
+
337
+ ### What Happens When It Runs
338
+
339
+ The scheduler daemon claims the occurrence and asks the selected session's model to process the prompt. The turn:
340
+
341
+ - Reopens the same session ID.
342
+ - Uses the same workspace on disk.
343
+ - Replays or anchors the existing conversation context.
344
+ - Retains the session's model, provider, reasoning, agents, and approval settings.
345
+ - Can read files changed since the previous turn.
346
+ - Can write files and run commands according to the session's durable permissions.
347
+ - Writes the response, tool calls, output, and outcome back to durable state.
348
+ - Appears in the scheduler inbox and session transcript.
349
+
350
+ Scheduled turns cannot wait for a human answer. In `review` and `code`, unremembered gated actions remain denied. In `unrestricted`, the session can execute available tools without confirmation. If a process is interrupted after a side effect may have occurred, the occurrence becomes unknown and must be explicitly resolved before a recurring job continues.
351
+
352
+ ### Keep Scheduled Work Safe and Useful
353
+
354
+ Write prompts that describe the desired autonomous boundary:
355
+
356
+ ```text
357
+ Review the latest test output. Read the changed files, run the focused tests, and fix only failures inside this workspace. Summarize every change and leave deployment untouched.
358
+ ```
359
+
360
+ For recurring sessions, make the prompt idempotent and ask for current inspection rather than assuming the previous turn completed. Store important external inputs in files or logs that the session can read.
361
+
362
+ ## Scheduler Job Types
363
+
364
+ Looking Glass supports three schedule types:
365
+
366
+ | Job | What it does | Best for |
367
+ | --- | --- | --- |
368
+ | `reminder` | Writes a durable inbox message | Human follow-ups and deadlines |
369
+ | `command` | Runs the exact stored Bash string | Deterministic tests, scripts, and maintenance |
370
+ | `session_prompt` | Runs one model turn in a persistent session | Context-aware project automation |
371
+
372
+ Create a reminder:
373
+
374
+ ```bash
375
+ glass cron reminder --once 2026-07-20T12:00:00Z "Review the deployment dashboard"
376
+ glass cron reminder --cron "0 9 * * 1-5" --timezone UTC "Review the deployment dashboard"
377
+ ```
378
+
379
+ Create a deterministic command. Pass the full shell command as one quoted argument so its exact text is preserved:
380
+
381
+ ```bash
382
+ glass cron command --once 2026-07-20T12:00:00Z "npm test"
383
+ glass cron command --cron "0 2 * * *" --cwd . "./scripts/backup.sh"
384
+ ```
385
+
386
+ Unlike `session_prompt`, a deterministic command does not use model context. It runs exactly the command stored in the job, with the configured timeout and output limit.
387
+
388
+ List and manage jobs:
389
+
390
+ ```bash
391
+ glass cron list
392
+ glass cron inbox
393
+ glass cron inbox --all
394
+ glass cron status
395
+ glass cron pause JOB_ID
396
+ glass cron resume JOB_ID
397
+ glass cron run JOB_ID
398
+ glass cron resolve JOB_ID
399
+ glass cron delete JOB_ID
400
+ glass cron ack INBOX_ID
401
+ ```
402
+
403
+ `run` queues one immediate occurrence. `resolve` acknowledges an unknown side-effect outcome so a blocked recurring job can continue. `ack` marks an inbox item as read.
404
+
405
+ ## Install the Scheduler Service
406
+
407
+ The scheduler must be running for schedules to execute while the TUI is closed. Build first, then install the user-level systemd service:
408
+
409
+ ```bash
410
+ npm run build
411
+ glass cron install
412
+ glass cron status
413
+ ```
414
+
415
+ The service is installed at:
416
+
417
+ ```text
418
+ ~/.config/systemd/user/looking-glass-scheduler.service
419
+ ```
420
+
421
+ It uses the current user's state database, takes one durable daemon lease, claims occurrences safely, fences stale workers after failure, and restarts on failure. The service does not delete scheduler state when uninstalled:
422
+
423
+ ```bash
424
+ glass cron uninstall
425
+ ```
426
+
427
+ Authenticated gateways used by scheduled prompts need their token available to the service. Keep it in a mode-`0600` environment file outside the repository:
428
+
429
+ ```bash
430
+ install -d -m 700 ~/.config/looking-glass
431
+ printf '%s\n' 'LM_STUDIO_API_KEY=replace-with-your-token' > ~/.config/looking-glass/scheduler.env
432
+ chmod 600 ~/.config/looking-glass/scheduler.env
433
+ ```
434
+
435
+ Exported environment variables take precedence. Never commit this file.
436
+
437
+ To run the daemon in the foreground for debugging:
438
+
439
+ ```bash
440
+ glass cron daemon
441
+ ```
442
+
443
+ ## Agents
444
+
445
+ The main model can call `run_agents` with up to eight self-contained tasks and bounded concurrency. Agents are useful for independent discovery, disjoint implementation, newly discovered branches, or focused review after a change.
446
+
447
+ ```text
448
+ /agentmodel lm-studio:example-model
449
+ /agentreasoning high
450
+ /agents on
451
+ ```
452
+
453
+ Each worker gets a hidden child session with isolated conversation history, response continuity, and tool records. The parent transcript is not copied, so delegated prompts should include the objective, relevant files, constraints, validation command, and expected return format.
454
+
455
+ Workers share the filesystem with the parent. Keep concurrent tasks independent or assign disjoint files. Leaf agents cannot recursively spawn agents, create schedules, or ask the operator questions. They inherit the parent's approval mode and remembered approvals.
456
+
457
+ ## Tools
458
+
459
+ The model can use these built-in tools:
460
+
461
+ | Tool | Function |
462
+ | --- | --- |
463
+ | `read` | Read files or bounded directory listings inside the workspace |
464
+ | `glob` | Find files with bounded `ripgrep` searches |
465
+ | `grep` | Search workspace text with bounded regular expressions |
466
+ | `apply_patch` | Apply atomic workspace patches |
467
+ | `bash` | Run bounded noninteractive Bash commands |
468
+ | `ask_user` | Ask the interactive operator a question |
469
+ | `run_agents` | Run isolated leaf-agent tasks concurrently |
470
+ | `schedule_create` | Create reminders, deterministic commands, or session prompts |
471
+ | `schedule_list` | List schedules and scoped scheduler inbox records |
472
+ | `schedule_manage` | Pause, resume, delete, run, resolve, or acknowledge schedules |
473
+
474
+ File tools are workspace-bound and symlink-aware. Bash disables startup profiles, bounds captured output, stores oversized results as artifacts, and terminates process groups on cancellation or timeout.
475
+
476
+ ## Approval Modes
477
+
478
+ Approval mode is durable per session and applies to both interactive and scheduled model turns:
479
+
480
+ | Mode | Reads | Normal writes | Bash | Persistent actions | Critical actions |
481
+ | --- | --- | --- | --- | --- | --- |
482
+ | `review` | No prompt | Prompt | Prompt | Prompt | Prompt |
483
+ | `code` | No prompt | No prompt | Prompt | Prompt | Prompt |
484
+ | `unrestricted` | No prompt | No prompt | No prompt | No prompt | No prompt |
485
+
486
+ Change the mode inside the TUI:
487
+
488
+ ```text
489
+ /permissions review
490
+ /permissions code
491
+ /permissions unrestricted
492
+ ```
493
+
494
+ `unrestricted` is fully noninteractive. It does not ask for confirmation for destructive commands, access-critical changes, schedules, or uncertain reruns. Risk is still classified for logging and display, but does not gate execution.
495
+
496
+ In `code`, choose `Always approve` when a command family should be reusable. Bash approvals are scoped by the leading executable: approving `cat one.txt` authorizes later commands starting with `cat`, regardless of arguments, redirects, working directory, timeout, risk classification, or compound suffix. Other tools use their canonical action arguments. Remembered approvals apply to the session's main turns, agents, and scheduled turns.
497
+
498
+ Looking Glass is not a sandbox. The process has the operating-system permissions of the user who launched it. Use `review` for unfamiliar repositories and reserve `unrestricted` for trusted local work.
499
+
500
+ ## State and Workspace Instructions
501
+
502
+ Default XDG locations:
503
+
504
+ | Data | Default path | Override |
505
+ | --- | --- | --- |
506
+ | Global config | `~/.config/looking-glass/` | `XDG_CONFIG_HOME` |
507
+ | SQLite state | `~/.local/share/looking-glass/state.db` | `LOOKING_GLASS_DB` |
508
+ | Artifacts | `~/.local/share/looking-glass/artifacts/` | `XDG_DATA_HOME` |
509
+ | Scheduler environment | `~/.config/looking-glass/scheduler.env` | fixed optional path |
510
+
511
+ State directories use mode `0700`. Large tool output is retained as a durable artifact and referenced from the model result. Do not commit the database, artifacts, credentials, `.env` files, or local configuration.
512
+
513
+ Looking Glass loads instruction files in this order:
514
+
515
+ 1. `~/.config/looking-glass/AGENTS.md`
516
+ 2. `<workspace>/AGENTS.md`
517
+ 3. Paths listed in the `instructions` configuration array
518
+
519
+ Instruction files can describe project conventions and operational context, but cannot create approval records or override a session's durable permissions. Only an explicit interactive `Always approve` decision creates reusable authorization.
520
+
521
+ ## Troubleshooting
522
+
523
+ Check the effective environment:
524
+
525
+ ```bash
526
+ glass config
527
+ glass doctor
528
+ glass models
529
+ ```
530
+
531
+ Common fixes:
532
+
533
+ - If the model list is empty, verify the gateway URL and API key environment variable.
534
+ - If a scheduled prompt does not run, verify the session is persistent and `glass cron status` shows an active daemon.
535
+ - If LM Studio schedules fail after the TUI exits, put the token in `~/.config/looking-glass/scheduler.env` with mode `0600`.
536
+ - If a recurring job is blocked, inspect `glass cron list`, review the unknown outcome, then run `glass cron resolve JOB_ID` deliberately.
537
+ - If a resumed session appears to have lost context, confirm you used `--session ID` and are looking at the same workspace and state database.
538
+ - After source changes, run `npm run build` before using the installed `glass` command or reinstalling the scheduler service.
539
+
540
+ ## Development
541
+
542
+ ```bash
543
+ npm ci
544
+ npm run typecheck
545
+ npm test
546
+ npm run build
547
+ npm run dev
548
+ npm pack --dry-run
549
+ ```
550
+
551
+ The build output is ignored by Git. The public source repository is:
552
+
553
+ ```text
554
+ https://github.com/S1gil0/lookingglass.git
555
+ ```
556
+
557
+ ## Repository Layout
558
+
559
+ ```text
560
+ src/
561
+ app.ts Application wiring and workspace discovery
562
+ cli.ts CLI entry point and scheduler commands
563
+ config.ts Global/workspace configuration loading
564
+ engine/ Conversation execution and context projection
565
+ model/ OpenAI-compatible gateway client integrations
566
+ scheduler/ Persistent jobs, leases, claims, runner, daemon
567
+ storage/ SQLite sessions, events, and artifacts
568
+ tools/ Coding tools, schemas, approvals, and safety policy
569
+ ui/ TUI and stdio interfaces
570
+ test/ Unit and integration coverage
571
+ looking-glass-title.svg README title graphic
572
+ ```
@@ -0,0 +1,21 @@
1
+ import type { CodexLbClient } from "../model/codex-lb.js";
2
+ import type { ArtifactStore } from "../storage/artifact-store.js";
3
+ import type { SessionStore } from "../storage/session-store.js";
4
+ import type { GatewayModel, GatewayProvider, GlassConfig } from "../types.js";
5
+ import type { ToolRegistry } from "../tools/registry.js";
6
+ import type { AgentBatchRunner, RunAgentsArgs } from "../tools/agents.js";
7
+ import type { ToolContext, ToolResult } from "../tools/types.js";
8
+ export declare class AgentCoordinator implements AgentBatchRunner {
9
+ private readonly config;
10
+ private readonly workspace;
11
+ private readonly sessions;
12
+ private readonly artifacts;
13
+ private readonly clientFor;
14
+ private readonly workerTools;
15
+ private readonly instructions;
16
+ private readonly modelFor;
17
+ constructor(config: GlassConfig, workspace: string, sessions: SessionStore, artifacts: ArtifactStore, clientFor: (provider: GatewayProvider) => CodexLbClient, workerTools: ToolRegistry, instructions: string | (() => string), modelFor: (id: string, provider: GatewayProvider, signal?: AbortSignal) => Promise<GatewayModel>);
18
+ private createEngine;
19
+ run(args: RunAgentsArgs, context: ToolContext): Promise<ToolResult>;
20
+ }
21
+ //# sourceMappingURL=coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/agents/coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAkB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA8CjE,qBAAa,gBAAiB,YAAW,gBAAgB;IAErD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAPR,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,aAAa,EACvD,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,EACrC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC;IAGnH,OAAO,CAAC,YAAY;IAad,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA4G1E"}