@onepointfour-packs/flaredeck-agent 0.2.203 → 0.2.204
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/dist/agent.d.ts +2 -1
- package/dist/agent.js +4 -3
- package/dist/agent.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js.map +1 -1
- package/dist/flaredeck-proxy.d.ts +7 -0
- package/dist/flaredeck-proxy.js +9 -0
- package/dist/flaredeck-proxy.js.map +1 -1
- package/dist/hydrate.d.ts +16 -0
- package/dist/hydrate.js +3 -1
- package/dist/hydrate.js.map +1 -1
- package/dist/jevguard.d.ts +3 -0
- package/dist/jevguard.js +10 -0
- package/dist/jevguard.js.map +1 -1
- package/dist/serve.js +24 -4
- package/dist/serve.js.map +1 -1
- package/dist/trusted-scripts.d.ts +34 -0
- package/dist/trusted-scripts.js +85 -0
- package/dist/trusted-scripts.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Checkout } from './workspace.js';
|
|
2
|
+
export type TrustedEntry = {
|
|
3
|
+
repository: string;
|
|
4
|
+
path: string;
|
|
5
|
+
sha256: string;
|
|
6
|
+
description: string;
|
|
7
|
+
};
|
|
8
|
+
/** An entry found on this machine. */
|
|
9
|
+
export type TrustedLocal = TrustedEntry & {
|
|
10
|
+
abs: string;
|
|
11
|
+
};
|
|
12
|
+
/** Where each entry is on this machine: in a checkout of its repository, when the file is there. */
|
|
13
|
+
export declare function locateScripts(entries: TrustedEntry[], here: Checkout[], exists?: (p: string) => boolean): TrustedLocal[];
|
|
14
|
+
/**
|
|
15
|
+
* Whether this command runs a trusted script, and nothing else. `ok`: run it unjudged. `changed`:
|
|
16
|
+
* it names a trusted script whose file no longer matches its checksum. Null: not a trusted script.
|
|
17
|
+
*
|
|
18
|
+
* Kept deliberately narrow: no `;`, `&&`, `||`, command substitution or redirects — only the script
|
|
19
|
+
* with its arguments, optionally piped into a reader (`| head -50`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function trustedRun(command: string, cwd: string, local: TrustedLocal[], read?: (p: string) => Buffer, home?: string): {
|
|
22
|
+
ok: TrustedLocal;
|
|
23
|
+
} | {
|
|
24
|
+
changed: TrustedLocal;
|
|
25
|
+
} | null;
|
|
26
|
+
/** A trusted script another agent runs: this one asks them. */
|
|
27
|
+
export type OthersScript = {
|
|
28
|
+
repository: string;
|
|
29
|
+
path: string;
|
|
30
|
+
description: string;
|
|
31
|
+
who: string[];
|
|
32
|
+
};
|
|
33
|
+
/** What a session is told: the scripts it may run here, and the ones to ask someone else for. */
|
|
34
|
+
export declare function trustedBrief(local: TrustedLocal[], others?: OthersScript[]): string;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scripts a person trusted in FlareDeck (Integrations → Scripts): run without the command guard
|
|
3
|
+
* judging them, so an agent can, say, read production logs through the one script that does only
|
|
4
|
+
* that (Cobus, 20 Oct). See flaredeck-mcp/src/vault/scripts.ts.
|
|
5
|
+
*
|
|
6
|
+
* An entry names a repository, a path in it, the SHA-256 a person approved, and what it is for.
|
|
7
|
+
* Here it is found in this machine's checkout of that repository, and a command is trusted only
|
|
8
|
+
* when it runs exactly that file AND the file's checksum still matches — so a script changed by
|
|
9
|
+
* anyone, an agent editing its own checkout included, is judged like any other command.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
13
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
14
|
+
import { repoIdentity } from './workspace.js';
|
|
15
|
+
const real = (p) => { try {
|
|
16
|
+
return realpathSync(p);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return resolve(p);
|
|
20
|
+
} };
|
|
21
|
+
/** Where each entry is on this machine: in a checkout of its repository, when the file is there. */
|
|
22
|
+
export function locateScripts(entries, here, exists = existsSync) {
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const e of entries) {
|
|
25
|
+
const want = `github.com/${String(e.repository).toLowerCase()}`;
|
|
26
|
+
for (const c of here) {
|
|
27
|
+
if (!c.origin || repoIdentity(c.origin) !== want)
|
|
28
|
+
continue;
|
|
29
|
+
const abs = join(c.path, e.path);
|
|
30
|
+
if (exists(abs) && !out.some((o) => o.abs === abs))
|
|
31
|
+
out.push({ ...e, abs });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
const sha256Of = (p, read) => {
|
|
37
|
+
try {
|
|
38
|
+
return createHash('sha256').update(read(p)).digest('hex');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/** What a trusted script's output may be piped into: reading and trimming, nothing that acts. */
|
|
45
|
+
const PIPE_OK = /^(head|tail|grep|egrep|jq|wc|cut|sort|uniq|tr|column)(\s|$)/;
|
|
46
|
+
/**
|
|
47
|
+
* Whether this command runs a trusted script, and nothing else. `ok`: run it unjudged. `changed`:
|
|
48
|
+
* it names a trusted script whose file no longer matches its checksum. Null: not a trusted script.
|
|
49
|
+
*
|
|
50
|
+
* Kept deliberately narrow: no `;`, `&&`, `||`, command substitution or redirects — only the script
|
|
51
|
+
* with its arguments, optionally piped into a reader (`| head -50`).
|
|
52
|
+
*/
|
|
53
|
+
export function trustedRun(command, cwd, local, read = (p) => readFileSync(p), home = process.env.HOME ?? '') {
|
|
54
|
+
if (!local.length)
|
|
55
|
+
return null;
|
|
56
|
+
const text = command.trim();
|
|
57
|
+
if (/[;&`<>]|\$\(|\|\|/.test(text.replace(/'[^']*'|"[^"$`]*"/g, '')))
|
|
58
|
+
return null;
|
|
59
|
+
const [first, ...pipes] = text.split(/\s*\|\s*/);
|
|
60
|
+
if (!first || pipes.some((p) => !PIPE_OK.test(p)))
|
|
61
|
+
return null;
|
|
62
|
+
const tokens = first.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
|
|
63
|
+
let i = 0;
|
|
64
|
+
if (/^(bash|sh|zsh)$/.test(tokens[0] ?? ''))
|
|
65
|
+
i = 1;
|
|
66
|
+
const raw = (tokens[i] ?? '').replace(/^["']|["']$/g, '');
|
|
67
|
+
if (!raw)
|
|
68
|
+
return null;
|
|
69
|
+
const expanded = raw.replace(/^~(?=\/)/, home).replace(/^\$\{?HOME\}?(?=\/)/, home);
|
|
70
|
+
const abs = real(isAbsolute(expanded) ? expanded : resolve(cwd, expanded));
|
|
71
|
+
const hit = local.find((l) => real(l.abs) === abs);
|
|
72
|
+
if (!hit)
|
|
73
|
+
return null;
|
|
74
|
+
return sha256Of(abs, read) === hit.sha256.toLowerCase() ? { ok: hit } : { changed: hit };
|
|
75
|
+
}
|
|
76
|
+
/** What a session is told: the scripts it may run here, and the ones to ask someone else for. */
|
|
77
|
+
export function trustedBrief(local, others = []) {
|
|
78
|
+
const lines = [];
|
|
79
|
+
if (local.length)
|
|
80
|
+
lines.push('', 'Scripts a person trusted for you — run them directly, they need no approval (piping the', 'output into head, tail, grep or jq is fine; chaining them with other commands is not):', ...local.map((l) => ` · \`${l.abs}\` — ${l.description}`), 'If one is refused as "changed", its file no longer matches what was approved: say so on the card.');
|
|
81
|
+
if (others.length)
|
|
82
|
+
lines.push('', 'Trusted scripts other agents run — you cannot. When you need one, ask one of them with', 'send-message (what to run it for, and the card), rather than finding another way:', ...others.map((o) => ` · ${o.path} in ${o.repository} — ${o.description}. Ask: ${o.who.join(' or ')}.`));
|
|
83
|
+
return lines.join('\n');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=trusted-scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-scripts.js","sourceRoot":"","sources":["../src/trusted-scripts.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onepointfour-packs/flaredeck-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.204",
|
|
4
4
|
"description": "Run a FlareDeck agent on your own machine: it picks up cards assigned to it, works each one in a checkout of its own, and reports back on the card.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|