@stfade/pi-read-delegator 1.0.6 → 1.0.7
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/index.d.ts +12 -0
- package/index.js +95 -78
- package/package.json +1 -1
- package/reader-manager.d.ts +8 -5
- package/reader-manager.js +28 -20
- package/ui.d.ts +1 -1
- package/ui.js +18 -7
package/index.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index.ts — pi-read-delegator entry point
|
|
3
|
+
*
|
|
4
|
+
* Blocks read tools from the orchestrator and tells it to delegate every
|
|
5
|
+
* file-read / search task to the 'reader' subagent.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Factory body: registration only (pi.on, pi.registerCommand, ensureReaderTemplate)
|
|
9
|
+
* - session_start: dependency check → tool blocking → status bar
|
|
10
|
+
* - before_agent_start: inject orchestrator system prompt
|
|
11
|
+
* - tool_call: intercept bash read commands → redirect to reader
|
|
12
|
+
*/
|
|
1
13
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
14
|
export default function (pi: ExtensionAPI): Promise<void>;
|
|
3
15
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* index.ts — pi-read-delegator entry point
|
|
4
|
+
*
|
|
5
|
+
* Blocks read tools from the orchestrator and tells it to delegate every
|
|
6
|
+
* file-read / search task to the 'reader' subagent.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* - Factory body: registration only (pi.on, pi.registerCommand, ensureReaderTemplate)
|
|
10
|
+
* - session_start: dependency check → tool blocking → status bar
|
|
11
|
+
* - before_agent_start: inject orchestrator system prompt
|
|
12
|
+
* - tool_call: intercept bash read commands → redirect to reader
|
|
13
|
+
*/
|
|
2
14
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
15
|
if (k2 === undefined) k2 = k;
|
|
4
16
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -37,19 +49,12 @@ exports.default = default_1;
|
|
|
37
49
|
const fs = __importStar(require("node:fs"));
|
|
38
50
|
const os = __importStar(require("node:os"));
|
|
39
51
|
const path = __importStar(require("node:path"));
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"For any file reading, searching, or directory listing, use the",
|
|
47
|
-
"'subagent' tool with agent='reader'.",
|
|
48
|
-
'Example: subagent(agent: "reader", task: "Find all TS files that import \'lodash\'")',
|
|
49
|
-
"Never try to use read, grep, find, or ls yourself. Always delegate.",
|
|
50
|
-
].join("\n"),
|
|
51
|
-
language: "auto",
|
|
52
|
-
};
|
|
52
|
+
const config_1 = require("./config");
|
|
53
|
+
const reader_manager_1 = require("./reader-manager");
|
|
54
|
+
const ui_1 = require("./ui");
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Bash read commands — these are intercepted and redirected to reader
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
53
58
|
const READ_BASH_COMMANDS = new Set([
|
|
54
59
|
"cat",
|
|
55
60
|
"grep",
|
|
@@ -74,45 +79,12 @@ const READ_BASH_COMMANDS = new Set([
|
|
|
74
79
|
"type",
|
|
75
80
|
"dir",
|
|
76
81
|
]);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Reader template path
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
80
85
|
function readerPath() {
|
|
81
86
|
return path.join(os.homedir(), ".pi", "agent", "agents", "reader.md");
|
|
82
87
|
}
|
|
83
|
-
function loadConfig() {
|
|
84
|
-
const cp = configPath();
|
|
85
|
-
try {
|
|
86
|
-
if (fs.existsSync(cp)) {
|
|
87
|
-
const raw = fs.readFileSync(cp, "utf8");
|
|
88
|
-
const parsed = JSON.parse(raw);
|
|
89
|
-
return { ...DEFAULT_CONFIG, ...parsed };
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
// corrupt file --- fall back to defaults
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
const dir = path.dirname(cp);
|
|
97
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
98
|
-
fs.writeFileSync(cp, JSON.stringify(DEFAULT_CONFIG, null, 2), "utf8");
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// read-only home directory --- ignore
|
|
102
|
-
}
|
|
103
|
-
return { ...DEFAULT_CONFIG };
|
|
104
|
-
}
|
|
105
|
-
function saveConfig(config) {
|
|
106
|
-
const cp = configPath();
|
|
107
|
-
try {
|
|
108
|
-
const dir = path.dirname(cp);
|
|
109
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
110
|
-
fs.writeFileSync(cp, JSON.stringify(config, null, 2), "utf8");
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
// read-only home directory --- ignore
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
88
|
async function ensureReaderTemplate() {
|
|
117
89
|
const rp = readerPath();
|
|
118
90
|
if (fs.existsSync(rp))
|
|
@@ -135,31 +107,70 @@ async function ensureReaderTemplate() {
|
|
|
135
107
|
await fs.promises.writeFile(rp, content, "utf8");
|
|
136
108
|
}
|
|
137
109
|
catch {
|
|
138
|
-
// read-only home directory
|
|
110
|
+
// read-only home directory — template creation is best-effort
|
|
139
111
|
}
|
|
140
112
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
*
|
|
146
|
-
*/
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Tool helpers
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
/** Determine which tools stay active after blocking read tools.
|
|
117
|
+
* Always keeps "subagent" — the bridge to the reader. */
|
|
147
118
|
function computeActiveTools(pi, blocked) {
|
|
148
119
|
const all = pi.getAllTools();
|
|
149
120
|
const blockedSet = new Set(blocked);
|
|
150
|
-
// Always keep "subagent" --- it is the bridge to the reader.
|
|
151
121
|
const forceKeep = new Set(["subagent"]);
|
|
152
122
|
return all
|
|
153
123
|
.map((t) => t.name)
|
|
154
124
|
.filter((name) => forceKeep.has(name) || !blockedSet.has(name));
|
|
155
125
|
}
|
|
156
126
|
// ---------------------------------------------------------------------------
|
|
157
|
-
// Extension
|
|
127
|
+
// Extension factory — registration only; actions go inside events
|
|
158
128
|
// ---------------------------------------------------------------------------
|
|
159
129
|
async function default_1(pi) {
|
|
160
|
-
const config = loadConfig();
|
|
161
|
-
//
|
|
162
|
-
|
|
130
|
+
const config = (0, config_1.loadConfig)();
|
|
131
|
+
// Detect language
|
|
132
|
+
(0, ui_1.getLanguage)(config.language);
|
|
133
|
+
// Quick sync dependency check — interactive prompt is deferred to
|
|
134
|
+
// session_start where we have access to ctx.ui.confirm().
|
|
135
|
+
let depsReady = (0, reader_manager_1.isSubagentsInstalled)();
|
|
136
|
+
let depsChecked = depsReady; // if already ready, no need to check again
|
|
137
|
+
// -----------------------------------------------------------------------
|
|
138
|
+
// 1. session_start: dependency check → tool blocking → status bar
|
|
139
|
+
// -----------------------------------------------------------------------
|
|
140
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
141
|
+
// --- Dependency check ---
|
|
142
|
+
if (!depsChecked) {
|
|
143
|
+
// Build a prompt function backed by ctx.ui.confirm()
|
|
144
|
+
const promptFn = async (message) => {
|
|
145
|
+
const ok = await ctx.ui.confirm("pi-subagents required", message);
|
|
146
|
+
return ok ? "y" : "n";
|
|
147
|
+
};
|
|
148
|
+
depsReady = await (0, reader_manager_1.checkDependencies)(promptFn);
|
|
149
|
+
depsChecked = true;
|
|
150
|
+
if (!depsReady) {
|
|
151
|
+
// Dependency missing and user declined / install failed
|
|
152
|
+
config.enabled = false;
|
|
153
|
+
(0, config_1.saveConfig)(config, { silent: true });
|
|
154
|
+
ctx.ui.setStatus("read-delegator", (0, ui_1.msg)("status_error"));
|
|
155
|
+
ctx.ui.notify((0, ui_1.msg)("deps_disabled"), "warning");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// If deps are now ready, re-enable config in case user previously
|
|
159
|
+
// declined but now installed manually before session start.
|
|
160
|
+
if (!config.enabled) {
|
|
161
|
+
config.enabled = true;
|
|
162
|
+
(0, config_1.saveConfig)(config, { silent: true });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// --- Tool blocking ---
|
|
166
|
+
if (config.enabled) {
|
|
167
|
+
pi.setActiveTools(computeActiveTools(pi, config.blocked_tools));
|
|
168
|
+
}
|
|
169
|
+
ctx.ui.setStatus("read-delegator", config.enabled ? (0, ui_1.msg)("status_active") : (0, ui_1.msg)("status_off"));
|
|
170
|
+
});
|
|
171
|
+
// -----------------------------------------------------------------------
|
|
172
|
+
// 2. before_agent_start: inject orchestrator system prompt
|
|
173
|
+
// -----------------------------------------------------------------------
|
|
163
174
|
pi.on("before_agent_start", async (event, _ctx) => {
|
|
164
175
|
if (!config.enabled)
|
|
165
176
|
return;
|
|
@@ -167,19 +178,16 @@ async function default_1(pi) {
|
|
|
167
178
|
systemPrompt: event.systemPrompt + "\n\n" + config.orchestrator_prompt,
|
|
168
179
|
};
|
|
169
180
|
});
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
pi.setActiveTools(computeActiveTools(pi, config.blocked_tools));
|
|
174
|
-
}
|
|
175
|
-
ctx.ui.setStatus("read-delegator", config.enabled ? "● reader: " + config.reader_subagent_name : undefined);
|
|
176
|
-
});
|
|
177
|
-
// Intercept bash read commands
|
|
181
|
+
// -----------------------------------------------------------------------
|
|
182
|
+
// 3. tool_call: intercept bash read commands
|
|
183
|
+
// -----------------------------------------------------------------------
|
|
178
184
|
pi.on("tool_call", async (event, _ctx) => {
|
|
179
185
|
if (!config.enabled)
|
|
180
186
|
return;
|
|
181
187
|
if (event.toolName === "bash" || event.toolName === "shell") {
|
|
182
188
|
const command = String(event.input?.command ?? "");
|
|
189
|
+
if (!command)
|
|
190
|
+
return;
|
|
183
191
|
const firstWord = command.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
184
192
|
if (READ_BASH_COMMANDS.has(firstWord)) {
|
|
185
193
|
return {
|
|
@@ -196,7 +204,9 @@ async function default_1(pi) {
|
|
|
196
204
|
}
|
|
197
205
|
}
|
|
198
206
|
});
|
|
199
|
-
//
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
// 4. /read-delegator command
|
|
209
|
+
// -----------------------------------------------------------------------
|
|
200
210
|
pi.registerCommand("read-delegator", {
|
|
201
211
|
description: "Manage read delegation (on|off|status)",
|
|
202
212
|
handler: async (args, ctx) => {
|
|
@@ -204,20 +214,24 @@ async function default_1(pi) {
|
|
|
204
214
|
switch (sub) {
|
|
205
215
|
case "on":
|
|
206
216
|
case "enable": {
|
|
217
|
+
if (!depsReady) {
|
|
218
|
+
ctx.ui.notify("pi-subagents not installed. Install it first to enable read delegation.", "warning");
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
207
221
|
config.enabled = true;
|
|
208
|
-
saveConfig(config);
|
|
222
|
+
(0, config_1.saveConfig)(config, { silent: true });
|
|
209
223
|
pi.setActiveTools(computeActiveTools(pi, config.blocked_tools));
|
|
210
|
-
ctx.ui.notify("
|
|
211
|
-
ctx.ui.setStatus("read-delegator",
|
|
224
|
+
ctx.ui.notify((0, ui_1.msg)("enabled"), "info");
|
|
225
|
+
ctx.ui.setStatus("read-delegator", (0, ui_1.msg)("status_active"));
|
|
212
226
|
return;
|
|
213
227
|
}
|
|
214
228
|
case "off":
|
|
215
229
|
case "disable": {
|
|
216
230
|
config.enabled = false;
|
|
217
|
-
saveConfig(config);
|
|
231
|
+
(0, config_1.saveConfig)(config, { silent: true });
|
|
218
232
|
pi.setActiveTools(pi.getAllTools().map((t) => t.name));
|
|
219
|
-
ctx.ui.notify("
|
|
220
|
-
ctx.ui.setStatus("read-delegator",
|
|
233
|
+
ctx.ui.notify((0, ui_1.msg)("disabled"), "info");
|
|
234
|
+
ctx.ui.setStatus("read-delegator", (0, ui_1.msg)("status_off"));
|
|
221
235
|
return;
|
|
222
236
|
}
|
|
223
237
|
case "status":
|
|
@@ -225,8 +239,9 @@ async function default_1(pi) {
|
|
|
225
239
|
const lines = [
|
|
226
240
|
"Read delegation: " +
|
|
227
241
|
(config.enabled ? "🟢 enabled" : "🔴 disabled"),
|
|
228
|
-
"Blocked tools: " + config.blocked_tools.join(", "),
|
|
229
242
|
"Reader subagent: " + config.reader_subagent_name,
|
|
243
|
+
"Dependencies: " + (depsReady ? "✅ ready" : "❌ missing"),
|
|
244
|
+
"Blocked tools: " + config.blocked_tools.join(", "),
|
|
230
245
|
];
|
|
231
246
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
232
247
|
return;
|
|
@@ -234,7 +249,9 @@ async function default_1(pi) {
|
|
|
234
249
|
}
|
|
235
250
|
},
|
|
236
251
|
});
|
|
237
|
-
//
|
|
252
|
+
// -----------------------------------------------------------------------
|
|
253
|
+
// 5. Background: ensure reader.md template
|
|
254
|
+
// -----------------------------------------------------------------------
|
|
238
255
|
await ensureReaderTemplate();
|
|
239
256
|
}
|
|
240
257
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
package/reader-manager.d.ts
CHANGED
|
@@ -24,14 +24,17 @@ export declare class ReaderError extends Error {
|
|
|
24
24
|
/**
|
|
25
25
|
* Verify that pi-subagents is installed as a Pi extension.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
* If not,
|
|
29
|
-
*
|
|
27
|
+
* - Uses `require.resolve('pi-subagents')` to check installation.
|
|
28
|
+
* - If not installed, prompts the user to install via `pi install pi-subagents`.
|
|
29
|
+
* - If the user declines or installation fails, returns false (caller disables the extension).
|
|
30
30
|
*
|
|
31
|
-
* @returns true if installed or successfully installed
|
|
32
|
-
* @throws if the user declines or installation fails
|
|
31
|
+
* @returns true if installed or successfully installed; false otherwise
|
|
33
32
|
*/
|
|
34
33
|
export declare function checkDependencies(prompt: (message: string) => Promise<string>): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Quick synchronous check: can we resolve pi-subagents?
|
|
36
|
+
*/
|
|
37
|
+
export declare function isSubagentsInstalled(): boolean;
|
|
35
38
|
/**
|
|
36
39
|
* Ensure the reader.md subagent template exists.
|
|
37
40
|
* If not, copy the bundled template from `templates/reader.md`.
|
package/reader-manager.js
CHANGED
|
@@ -44,6 +44,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.ReaderError = void 0;
|
|
46
46
|
exports.checkDependencies = checkDependencies;
|
|
47
|
+
exports.isSubagentsInstalled = isSubagentsInstalled;
|
|
47
48
|
exports.ensureReaderTemplate = ensureReaderTemplate;
|
|
48
49
|
exports.callReader = callReader;
|
|
49
50
|
exports.handleReaderError = handleReaderError;
|
|
@@ -76,28 +77,31 @@ const READER_TEMPLATE_PATH = expandTilde("~/.pi/agent/agents/reader.md");
|
|
|
76
77
|
/**
|
|
77
78
|
* Verify that pi-subagents is installed as a Pi extension.
|
|
78
79
|
*
|
|
79
|
-
*
|
|
80
|
-
* If not,
|
|
81
|
-
*
|
|
80
|
+
* - Uses `require.resolve('pi-subagents')` to check installation.
|
|
81
|
+
* - If not installed, prompts the user to install via `pi install pi-subagents`.
|
|
82
|
+
* - If the user declines or installation fails, returns false (caller disables the extension).
|
|
82
83
|
*
|
|
83
|
-
* @returns true if installed or successfully installed
|
|
84
|
-
* @throws if the user declines or installation fails
|
|
84
|
+
* @returns true if installed or successfully installed; false otherwise
|
|
85
85
|
*/
|
|
86
86
|
async function checkDependencies(prompt) {
|
|
87
|
-
//
|
|
88
|
-
|
|
87
|
+
// Already installed — nothing to do
|
|
88
|
+
try {
|
|
89
|
+
require.resolve("pi-subagents");
|
|
89
90
|
return true;
|
|
90
91
|
}
|
|
92
|
+
catch {
|
|
93
|
+
// MODULE_NOT_FOUND — prompt the user
|
|
94
|
+
}
|
|
91
95
|
console.warn("[pi-read-delegator] ⚠️ pi-subagents is not installed.");
|
|
92
|
-
const answer = await prompt("
|
|
96
|
+
const answer = await prompt("pi-subagents is not installed. Install it now? [Y/n]");
|
|
93
97
|
const normalized = answer.trim().toLowerCase();
|
|
94
98
|
if (normalized !== "" && normalized !== "y" && normalized !== "yes") {
|
|
95
|
-
|
|
99
|
+
console.error("[pi-read-delegator] ❌ Cannot proceed without pi-subagents. Extension disabled.");
|
|
100
|
+
return false;
|
|
96
101
|
}
|
|
97
102
|
// Attempt installation
|
|
98
103
|
console.log("[pi-read-delegator] 📦 Installing pi-subagents…");
|
|
99
104
|
try {
|
|
100
|
-
// Try `pi install pi-subagents` first (the Pi package manager)
|
|
101
105
|
(0, child_process_1.execSync)("pi install pi-subagents", {
|
|
102
106
|
stdio: "pipe",
|
|
103
107
|
timeout: 60_000,
|
|
@@ -105,7 +109,7 @@ async function checkDependencies(prompt) {
|
|
|
105
109
|
});
|
|
106
110
|
console.log("[pi-read-delegator] ✅ pi-subagents installed via pi.");
|
|
107
111
|
}
|
|
108
|
-
catch {
|
|
112
|
+
catch (firstErr) {
|
|
109
113
|
// Fallback to global npm install
|
|
110
114
|
try {
|
|
111
115
|
(0, child_process_1.execSync)("npm install -g pi-subagents", {
|
|
@@ -115,24 +119,28 @@ async function checkDependencies(prompt) {
|
|
|
115
119
|
});
|
|
116
120
|
console.log("[pi-read-delegator] ✅ pi-subagents installed via npm.");
|
|
117
121
|
}
|
|
118
|
-
catch (
|
|
119
|
-
|
|
122
|
+
catch (secondErr) {
|
|
123
|
+
console.error("[pi-read-delegator] ❌ Cannot proceed without pi-subagents. Extension disabled.");
|
|
124
|
+
return false;
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
// Verify installation took effect
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
try {
|
|
129
|
+
require.resolve("pi-subagents");
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
console.error("[pi-read-delegator] ❌ pi-subagents installed but cannot be found. Restart Pi and try again.");
|
|
134
|
+
return false;
|
|
125
135
|
}
|
|
126
|
-
return true;
|
|
127
136
|
}
|
|
128
137
|
/**
|
|
129
|
-
*
|
|
138
|
+
* Quick synchronous check: can we resolve pi-subagents?
|
|
130
139
|
*/
|
|
131
140
|
function isSubagentsInstalled() {
|
|
132
141
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return mod !== undefined;
|
|
142
|
+
require.resolve("pi-subagents");
|
|
143
|
+
return true;
|
|
136
144
|
}
|
|
137
145
|
catch {
|
|
138
146
|
return false;
|
package/ui.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Detects the user's language preference (config → Pi settings → OS → "en")
|
|
5
5
|
* and provides localized messages. Manages a status bar indicator.
|
|
6
6
|
*/
|
|
7
|
-
export type Status = "active" | "idle" | "error";
|
|
7
|
+
export type Status = "active" | "idle" | "error" | "off";
|
|
8
8
|
/** Minimal Pi agent interface for the status bar API. */
|
|
9
9
|
export interface AgentWithStatusBar {
|
|
10
10
|
/** Set text to display in the Pi status bar. */
|
package/ui.js
CHANGED
|
@@ -84,17 +84,25 @@ const messages = {
|
|
|
84
84
|
tr: "❌ Kurulum başarısız. Elle yükleyin.",
|
|
85
85
|
en: "❌ Installation failed. Install manually.",
|
|
86
86
|
},
|
|
87
|
+
deps_disabled: {
|
|
88
|
+
tr: "pi-subagents olmadan devam edilemez. Eklenti devre dışı.",
|
|
89
|
+
en: "Cannot proceed without pi-subagents. Extension disabled.",
|
|
90
|
+
},
|
|
87
91
|
status_active: {
|
|
88
|
-
tr: "
|
|
89
|
-
en: "
|
|
92
|
+
tr: "🟢 reader",
|
|
93
|
+
en: "🟢 reader",
|
|
90
94
|
},
|
|
91
95
|
status_idle: {
|
|
92
|
-
tr: "○
|
|
93
|
-
en: "○
|
|
96
|
+
tr: "○ reader",
|
|
97
|
+
en: "○ reader",
|
|
94
98
|
},
|
|
95
99
|
status_error: {
|
|
96
|
-
tr: "⚠
|
|
97
|
-
en: "⚠
|
|
100
|
+
tr: "⚠ reader",
|
|
101
|
+
en: "⚠ reader",
|
|
102
|
+
},
|
|
103
|
+
status_off: {
|
|
104
|
+
tr: "🔴 reader",
|
|
105
|
+
en: "🔴 reader",
|
|
98
106
|
},
|
|
99
107
|
blocked: {
|
|
100
108
|
tr: "🚫 Engellendi: ",
|
|
@@ -217,12 +225,15 @@ function updateStatusBar(status) {
|
|
|
217
225
|
case "error":
|
|
218
226
|
text = msg("status_error");
|
|
219
227
|
break;
|
|
228
|
+
case "off":
|
|
229
|
+
text = msg("status_off");
|
|
230
|
+
break;
|
|
220
231
|
default:
|
|
221
232
|
text = msg("status_idle");
|
|
222
233
|
break;
|
|
223
234
|
}
|
|
224
235
|
try {
|
|
225
|
-
statusBarAgent.setStatusBarText(
|
|
236
|
+
statusBarAgent.setStatusBarText(text);
|
|
226
237
|
}
|
|
227
238
|
catch {
|
|
228
239
|
// Graceful fallback — not all Pi versions support status bar
|