opencode-swarm 7.149.1 → 7.151.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.
- package/dist/cli/{config-doctor-d3nsq1nz.js → config-doctor-23ega26j.js} +2 -2
- package/dist/cli/{core-y9d858n6.js → core-3g4krkj8.js} +1 -1
- package/dist/cli/{curation-policy-nck9g765.js → curation-policy-fmvccdrg.js} +6 -6
- package/dist/cli/{curator-llm-factory-mzh9ns5s.js → curator-llm-factory-k0nxn5gt.js} +28 -28
- package/dist/cli/{curator-f5m0hh2p.js → curator-rym2wtn6.js} +28 -28
- package/dist/cli/{evidence-summary-service-601x7ne7.js → evidence-summary-service-f0gvjesf.js} +12 -12
- package/dist/cli/{gate-evidence-kjs9vsx9.js → gate-evidence-cghq17xc.js} +6 -6
- package/dist/cli/{guardrail-explain-j291sss5.js → guardrail-explain-cv52smw2.js} +29 -29
- package/dist/cli/{guardrail-log-1jykfrqc.js → guardrail-log-wgwmh9b7.js} +5 -5
- package/dist/cli/{guardrail-reset-tr07m077.js → guardrail-reset-vx7zsmzd.js} +28 -28
- package/dist/cli/{hive-promoter-162ws6xp.js → hive-promoter-jb2nzv3j.js} +28 -28
- package/dist/cli/{index-yjj3s8af.js → index-02qc4ehj.js} +3 -3
- package/dist/cli/{index-k2sm9677.js → index-0q2mjxp2.js} +1 -1
- package/dist/cli/index-2qte9nr7.js +149 -0
- package/dist/cli/{index-srwp8fs7.js → index-5ep31be7.js} +4 -4
- package/dist/cli/{index-exn0ztsv.js → index-6zkm4p7p.js} +1 -1
- package/dist/cli/{index-cqhf7fkw.js → index-7qbyetsf.js} +1 -1
- package/dist/cli/{index-64d17yd0.js → index-8wy7pb4a.js} +2 -2
- package/dist/cli/{index-prxrmc3b.js → index-9wpr1p2g.js} +2 -2
- package/dist/cli/{index-xggpmtfx.js → index-aw492hpn.js} +57 -40
- package/dist/cli/{index-ekvs3ade.js → index-bfc4bbq4.js} +7 -7
- package/dist/cli/{index-dtmgt2xn.js → index-dvycdkhj.js} +1 -0
- package/dist/cli/{index-fc4x86sy.js → index-e9qh1j19.js} +5 -5
- package/dist/cli/{index-4sdhbxgq.js → index-f73px21b.js} +1 -1
- package/dist/cli/{index-pf22x0dr.js → index-fkqfcv14.js} +2 -1
- package/dist/cli/{index-apwcvfjt.js → index-frp2hwdg.js} +2 -2
- package/dist/cli/{index-7m8rk72d.js → index-fybg880e.js} +1315 -445
- package/dist/cli/{index-n99s022c.js → index-jjpppdvb.js} +1 -1
- package/dist/cli/{index-kgk65rde.js → index-kghpgs47.js} +1 -1
- package/dist/cli/{index-cna8m7my.js → index-qa8bmwav.js} +745 -8
- package/dist/cli/{index-mdwtj4xm.js → index-sdff3rvj.js} +6 -6
- package/dist/cli/{index-hxbrsb40.js → index-sg48w5e4.js} +2 -2
- package/dist/cli/{index-t994f8fp.js → index-tfkc0zf4.js} +1 -1
- package/dist/cli/{index-38ema5k2.js → index-tp1avc8j.js} +2 -2
- package/dist/cli/{index-m8dn0qnm.js → index-txbd25bc.js} +1 -1
- package/dist/cli/{index-jb9tb1sd.js → index-v3gshkpz.js} +1 -1
- package/dist/cli/{index-f53yyerg.js → index-vradyw0x.js} +30 -30
- package/dist/cli/{index-1aztaa2s.js → index-vs8wtavs.js} +3 -3
- package/dist/cli/{index-dkrz1vv5.js → index-wna9f75x.js} +4 -4
- package/dist/cli/{index-xe83cwvn.js → index-wxkgy9gh.js} +7 -7
- package/dist/cli/{index-jg2gwzvq.js → index-xeptzfb6.js} +4 -4
- package/dist/cli/{index-vy6q9d8j.js → index-z4bg1hv8.js} +1 -1
- package/dist/cli/{index-5gntxwxt.js → index-zkxnba57.js} +5 -5
- package/dist/cli/index.js +28 -28
- package/dist/cli/{knowledge-escalator-whkxxgxj.js → knowledge-escalator-a9dwxqz8.js} +11 -11
- package/dist/cli/{knowledge-events-rnqzt87h.js → knowledge-events-0q4sb713.js} +9 -9
- package/dist/cli/{knowledge-link-mzn8x0qd.js → knowledge-link-v7hj1h8m.js} +5 -5
- package/dist/cli/{knowledge-store-7de59rnz.js → knowledge-store-y2nbt9jk.js} +6 -6
- package/dist/cli/{knowledge-validator-bpk17jf4.js → knowledge-validator-4wr1m0xa.js} +8 -8
- package/dist/cli/{pending-delegations-qzy6rnvw.js → pending-delegations-a2nmssr1.js} +3 -3
- package/dist/cli/{pr-subscriptions-q862pvz1.js → pr-subscriptions-7879nq5k.js} +3 -3
- package/dist/cli/{runner-1aygs98c.js → runner-7znestx4.js} +6 -6
- package/dist/cli/{scan-cursor-0p51fh61.js → scan-cursor-bsrfrxm6.js} +7 -7
- package/dist/cli/{schema-8g2nxhjf.js → schema-s6yh3rst.js} +1 -1
- package/dist/cli/{scope-persistence-hhkr0c46.js → scope-persistence-f77w4jrx.js} +8 -8
- package/dist/cli/{skill-generator-pk9gcz7r.js → skill-generator-jr7c8fcg.js} +13 -13
- package/dist/cli/{telemetry-5deacb7w.js → telemetry-52pw5xac.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-9v8e0dz7.js → worktree-collision-ownership-p31zm5k0.js} +3 -3
- package/dist/cli/{worktree-isolation-1hwwfbdw.js → worktree-isolation-ka20b0rm.js} +28 -28
- package/dist/commands/close.d.ts +1 -0
- package/dist/hooks/guardrails/audit-log.d.ts +70 -19
- package/dist/hooks/guardrails/helpers.d.ts +16 -1
- package/dist/hooks/guardrails/shell-audit-store.d.ts +211 -0
- package/dist/hooks/guardrails/tool-before.d.ts +0 -2
- package/dist/index.js +415 -371
- package/dist/lang/symbol-graph.d.ts +15 -0
- package/dist/observability/catalog.d.ts +7 -5
- package/dist/services/guardrail-log-service.d.ts +4 -0
- package/dist/telemetry.d.ts +22 -1
- package/dist/tools/repo-graph/builder.d.ts +27 -1
- package/dist/tools/symbols.d.ts +35 -0
- package/package.json +2 -1
- package/dist/cli/index-eaq9b0qm.js +0 -110
|
@@ -50,3 +50,18 @@ export interface FileSymbolFacts {
|
|
|
50
50
|
* @returns FileSymbolFacts, or null on failure
|
|
51
51
|
*/
|
|
52
52
|
export declare function extractFileSymbols(grammarId: string, source: string): Promise<FileSymbolFacts | null>;
|
|
53
|
+
declare function parseDartImport(text: string): FileSymbolFacts['imports'][0] | FileSymbolFacts['imports'] | null;
|
|
54
|
+
declare function parseRubyRequire(text: string): FileSymbolFacts['imports'][0] | null;
|
|
55
|
+
declare function parsePhpUse(text: string): FileSymbolFacts['imports'][0] | null;
|
|
56
|
+
/**
|
|
57
|
+
* DI seam for direct parser tests — the import parsers are module-private by
|
|
58
|
+
* design; tests exercise them through this seam instead of `mock.module`,
|
|
59
|
+
* which leaks across Bun's shared test-runner process (@see AGENTS.md
|
|
60
|
+
* invariant #7; PR #2361 review R10/PRR-017).
|
|
61
|
+
*/
|
|
62
|
+
export declare const _internals: {
|
|
63
|
+
parseDartImport: typeof parseDartImport;
|
|
64
|
+
parseRubyRequire: typeof parseRubyRequire;
|
|
65
|
+
parsePhpUse: typeof parsePhpUse;
|
|
66
|
+
};
|
|
67
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The event catalog (issue #2029).
|
|
3
3
|
*
|
|
4
|
-
* Exactly
|
|
5
|
-
* `src/telemetry.ts:15-
|
|
4
|
+
* Exactly 49 entries, matching the `TelemetryEvent` union at
|
|
5
|
+
* `src/telemetry.ts:15-131`. Thirty-eight predate the #2029 contract; the 39th is
|
|
6
6
|
* `agent_conflict_detected` (previously emitted through a force-cast past the
|
|
7
7
|
* type system), the 40th is `close_archive_result` (issue #2030 — the
|
|
8
8
|
* structured close/archive result event), the 41st is the bounded diagnostic
|
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
* `.swarm/context-telemetry.jsonl` store, the 47th is the counts-only
|
|
16
16
|
* `skill_usage_health` storage audit for the issue-#2038
|
|
17
17
|
* `.swarm/skill-usage.jsonl` store and its authoritative pending sidecar,
|
|
18
|
-
*
|
|
19
|
-
* issue-#2039 `.swarm/events.jsonl` store
|
|
18
|
+
* the 48th is the bounded `core_events_health` storage audit for the
|
|
19
|
+
* issue-#2039 `.swarm/events.jsonl` store, and the 49th is the bounded
|
|
20
|
+
* `shell_audit_health` storage audit for the issue-#2040
|
|
21
|
+
* `.swarm/session/shell-audit.jsonl` security-audit store. These late additions are instances
|
|
20
22
|
* of the defect class this contract exists to close: an event kind entering
|
|
21
23
|
* the stream with no registration.
|
|
22
24
|
*
|
|
@@ -71,7 +73,7 @@ export interface CatalogEntry {
|
|
|
71
73
|
/**
|
|
72
74
|
* Whether an event of this kind must carry `trace.parentSpanId`.
|
|
73
75
|
*
|
|
74
|
-
* `false` for all
|
|
76
|
+
* `false` for all 49 entries today, and that is a truthful statement about
|
|
75
77
|
* the current system rather than a placeholder: no producer supplies a
|
|
76
78
|
* parent span, so `createObservation` never sets one. Setting this to `true`
|
|
77
79
|
* for a kind whose producer cannot supply a parent would make every
|
|
@@ -6,5 +6,9 @@ export interface GuardrailLogEntry {
|
|
|
6
6
|
tool: string;
|
|
7
7
|
command?: string;
|
|
8
8
|
path?: string;
|
|
9
|
+
/** 16-hex sha256 fingerprint of the redacted command (typed entries only);
|
|
10
|
+
* rendered as a correlation suffix so duplicate/related decisions can be
|
|
11
|
+
* linked without repeating command content. */
|
|
12
|
+
commandHash?: string;
|
|
9
13
|
}
|
|
10
14
|
export declare function handleGuardrailLog(directory: string, args: string[]): Promise<string>;
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activa
|
|
|
32
32
|
* `prm_hard_stop` TRIGGER emitted by `src/prm/escalation.ts`. A trigger with
|
|
33
33
|
* no matching delivery means the containment never reached the agent.
|
|
34
34
|
*/
|
|
35
|
-
| 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition' | 'knowledge_maintenance' | 'residue_health' | 'context_telemetry_health' | 'skill_usage_health' | 'core_events_health';
|
|
35
|
+
| 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition' | 'knowledge_maintenance' | 'residue_health' | 'context_telemetry_health' | 'skill_usage_health' | 'core_events_health' | 'shell_audit_health';
|
|
36
36
|
/** Stable classification for how a reviewer-gate decision was established. */
|
|
37
37
|
export type ReviewerGateEvidenceKind = 'genuine' | 'fallback' | 'data_quality' | 'block';
|
|
38
38
|
/**
|
|
@@ -314,6 +314,27 @@ export declare const telemetry: {
|
|
|
314
314
|
bytes: number;
|
|
315
315
|
limit_bytes: number;
|
|
316
316
|
}): void;
|
|
317
|
+
/**
|
|
318
|
+
* Shell-audit store health (issue #2040): emitted on compaction and close
|
|
319
|
+
* for the bounded `.swarm/session/shell-audit.jsonl` security-audit
|
|
320
|
+
* store. Counts ONLY — no command content, no filesystem paths, no agent
|
|
321
|
+
* or session identifiers, matching the observability contract's
|
|
322
|
+
* no-content-in-metrics rule (issue #2040 requirement 5). `dropped_count`
|
|
323
|
+
* discloses allowed-class decisions folded by the age ceiling;
|
|
324
|
+
* `compacted_count` budget folds (byte/count caps).
|
|
325
|
+
*/
|
|
326
|
+
shellAuditHealth(data: {
|
|
327
|
+
trigger: "compaction" | "close";
|
|
328
|
+
accepted_count: number;
|
|
329
|
+
compacted_count: number;
|
|
330
|
+
retained_count: number;
|
|
331
|
+
dropped_count: number;
|
|
332
|
+
corrupt_count: number;
|
|
333
|
+
oldest_timestamp: string | null;
|
|
334
|
+
newest_timestamp: string | null;
|
|
335
|
+
bytes: number;
|
|
336
|
+
limit_bytes: number;
|
|
337
|
+
}): void;
|
|
317
338
|
/**
|
|
318
339
|
* Issue #2063 C2 — the PRM hard-stop DENIAL was actually delivered to the
|
|
319
340
|
* agent (thrown by the guardrails `toolBefore` consumer). `prm_hard_stop`
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* used by both the builder and the incremental updater.
|
|
12
12
|
*/
|
|
13
13
|
import { extractFileSymbols } from '../../lang/symbol-graph';
|
|
14
|
-
import { extractGoSymbols, extractPythonSymbols, extractRustSymbols, extractTSSymbols } from '../symbols';
|
|
14
|
+
import { extractDartSymbols, extractGoSymbols, extractPhpSymbols, extractPythonSymbols, extractRubySymbols, extractRustSymbols, extractTSSymbols } from '../symbols';
|
|
15
15
|
import { extractFileOntology } from './ontology';
|
|
16
16
|
import { safeRealpathSync } from './safe-realpath';
|
|
17
17
|
import type { BuildWorkspaceGraphOptions, GraphEdge, GraphExtractorInputWitness, GraphNode, RepoGraph, RepoGraphDiagnostics, SymbolEdge } from './types';
|
|
@@ -28,7 +28,13 @@ export declare const _internals: {
|
|
|
28
28
|
extractPythonSymbols: typeof extractPythonSymbols;
|
|
29
29
|
extractRustSymbols: typeof extractRustSymbols;
|
|
30
30
|
extractGoSymbols: typeof extractGoSymbols;
|
|
31
|
+
extractDartSymbols: typeof extractDartSymbols;
|
|
32
|
+
extractRubySymbols: typeof extractRubySymbols;
|
|
33
|
+
extractPhpSymbols: typeof extractPhpSymbols;
|
|
31
34
|
parseFileImports: typeof parseFileImports;
|
|
35
|
+
parseDartFileImports: typeof parseDartFileImports;
|
|
36
|
+
parseRubyFileImports: typeof parseRubyFileImports;
|
|
37
|
+
parsePhpFileImports: typeof parsePhpFileImports;
|
|
32
38
|
extractFileOntology: typeof extractFileOntology;
|
|
33
39
|
stripComments: typeof stripComments;
|
|
34
40
|
computeUsedSymbols: typeof computeUsedSymbols;
|
|
@@ -132,6 +138,26 @@ interface ParsedImport {
|
|
|
132
138
|
*/
|
|
133
139
|
declare function stripComments(content: string): string;
|
|
134
140
|
declare function parseFileImports(rawContent: string, sourceFile?: string, workspaceRoot?: string): ParsedImport[];
|
|
141
|
+
/**
|
|
142
|
+
* Regex import fallback for Dart (see {@link parseCSharpFileImports}).
|
|
143
|
+
* `hide` clauses are intentionally unhandled — the import is still recorded
|
|
144
|
+
* as a namespace import (all symbols minus hidden ones), which is correct
|
|
145
|
+
* for graph purposes.
|
|
146
|
+
*/
|
|
147
|
+
declare function parseDartFileImports(rawContent: string): ParsedImport[];
|
|
148
|
+
/**
|
|
149
|
+
* Regex import fallback for Ruby require/require_relative. `require_relative`
|
|
150
|
+
* resolves against the requiring file's directory, so the specifier is
|
|
151
|
+
* normalized to './name' when no explicit relative prefix is present.
|
|
152
|
+
*/
|
|
153
|
+
declare function parseRubyFileImports(rawContent: string): ParsedImport[];
|
|
154
|
+
/**
|
|
155
|
+
* Regex import fallback for PHP `use` declarations. Grouped `use A\B, C\D;`
|
|
156
|
+
* forms are a known limitation (the whole group is skipped); FQN specifiers
|
|
157
|
+
* are recorded as-is — mapping them to workspace files requires composer
|
|
158
|
+
* PSR-4 awareness, which is out of scope (#1531 "where practical").
|
|
159
|
+
*/
|
|
160
|
+
declare function parsePhpFileImports(rawContent: string): ParsedImport[];
|
|
135
161
|
/**
|
|
136
162
|
* Conservatively determine which imported bindings are actually referenced in
|
|
137
163
|
* the importing file's body.
|
package/dist/tools/symbols.d.ts
CHANGED
|
@@ -19,5 +19,40 @@ export declare function extractTSSymbols(filePath: string, cwd: string): SymbolI
|
|
|
19
19
|
export declare function extractPythonSymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
20
20
|
export declare function extractRustSymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
21
21
|
export declare function extractGoSymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
22
|
+
/**
|
|
23
|
+
* Dart symbols: classes/mixins/enums/extensions and functions. Visibility is
|
|
24
|
+
* the `_`-prefix convention. Functions declared INSIDE a type body are
|
|
25
|
+
* emitted as qualified `TypeName.member` method symbols (mirroring the Swift
|
|
26
|
+
* extractor's naming) instead of being mislabeled as top-level functions;
|
|
27
|
+
* the qualification also keeps same-named members of different classes from
|
|
28
|
+
* collapsing in the name:kind dedup.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractDartSymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
31
|
+
/**
|
|
32
|
+
* Ruby symbols: modules, classes, constants, and `def` methods with
|
|
33
|
+
* `private`/`protected` section tracking. A nested class/module saves and
|
|
34
|
+
* restores the outer section (approximate `end`-balance tracking); targeted
|
|
35
|
+
* `private :sym` marks the named method. Singleton methods keep their `self.`
|
|
36
|
+
* qualification in the name. Dynamic constructs (`define_method`, `send`,
|
|
37
|
+
* metaprogramming) are invisible to this scanner by design.
|
|
38
|
+
*/
|
|
39
|
+
export declare function extractRubySymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
40
|
+
/**
|
|
41
|
+
* PHP symbols: namespaces, traits/interfaces/classes, functions and methods
|
|
42
|
+
* with visibility modifiers. Dynamic constructs (variable functions/classes,
|
|
43
|
+
* variable variables, Blade directives in `.blade.php`) are best-effort
|
|
44
|
+
* only — see docs/php-laravel.md.
|
|
45
|
+
*/
|
|
46
|
+
export declare function extractPhpSymbols(filePath: string, cwd: string): SymbolInfo[];
|
|
22
47
|
export declare const symbols: ToolDefinition;
|
|
48
|
+
/**
|
|
49
|
+
* DI seam for testability — tests substitute via `_internals.fn` rather than
|
|
50
|
+
* `mock.module`, which leaks across Bun's shared test-runner process.
|
|
51
|
+
* @see AGENTS.md invariant #7
|
|
52
|
+
*/
|
|
53
|
+
export declare const _internals: {
|
|
54
|
+
extractDartSymbols: typeof extractDartSymbols;
|
|
55
|
+
extractRubySymbols: typeof extractRubySymbols;
|
|
56
|
+
extractPhpSymbols: typeof extractPhpSymbols;
|
|
57
|
+
};
|
|
23
58
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.151.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"check:events": "bun run scripts/check-event-contract.ts",
|
|
111
111
|
"check:retention": "bun run scripts/check-retention-registry.ts",
|
|
112
112
|
"check:core-events": "bun run scripts/check-core-events-usage.ts",
|
|
113
|
+
"check:shell-audit": "bun run scripts/check-shell-audit-usage.ts",
|
|
113
114
|
"check:test-file-cap": "bun run scripts/check-test-file-cap.ts",
|
|
114
115
|
"check:pending-fragment": "bun run scripts/check-pending-fragment.ts",
|
|
115
116
|
"check:gate-portability": "bun run scripts/check-gate-portability.ts",
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
redactPath,
|
|
4
|
-
redactShellCommand
|
|
5
|
-
} from "./index-cna8m7my.js";
|
|
6
|
-
|
|
7
|
-
// src/services/guardrail-log-service.ts
|
|
8
|
-
import * as fs from "fs/promises";
|
|
9
|
-
import * as path from "path";
|
|
10
|
-
var BLOCK_TYPES = new Set([
|
|
11
|
-
"file_write",
|
|
12
|
-
"scope_violation",
|
|
13
|
-
"destructive_block"
|
|
14
|
-
]);
|
|
15
|
-
function isBlockEntry(entry) {
|
|
16
|
-
if (entry.type === null || entry.type === undefined)
|
|
17
|
-
return false;
|
|
18
|
-
return BLOCK_TYPES.has(entry.type);
|
|
19
|
-
}
|
|
20
|
-
function redactSummary(entry) {
|
|
21
|
-
if (entry.type === "file_write" || entry.type === "scope_violation") {
|
|
22
|
-
const raw = entry.path ?? "";
|
|
23
|
-
return redactPath(raw);
|
|
24
|
-
}
|
|
25
|
-
if (entry.type === "destructive_block" || entry.type === "sandbox_wrap" || entry.type === "sandbox_skip" || entry.type === "shell" || entry.type === null || entry.type === undefined) {
|
|
26
|
-
const raw = entry.command ?? "";
|
|
27
|
-
return redactShellCommand(raw);
|
|
28
|
-
}
|
|
29
|
-
return "";
|
|
30
|
-
}
|
|
31
|
-
function formatEntry(entry) {
|
|
32
|
-
const decisionType = entry.type ?? "shell";
|
|
33
|
-
const summary = redactSummary(entry);
|
|
34
|
-
return `- [${entry.ts}] ${decisionType} | agent: ${entry.agent} | ${summary}`;
|
|
35
|
-
}
|
|
36
|
-
async function handleGuardrailLog(directory, args) {
|
|
37
|
-
const auditPath = path.join(directory, ".swarm", "session", "shell-audit.jsonl");
|
|
38
|
-
let raw;
|
|
39
|
-
try {
|
|
40
|
-
raw = await fs.readFile(auditPath, "utf-8");
|
|
41
|
-
} catch (error) {
|
|
42
|
-
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
43
|
-
return "No guardrail decisions recorded yet.";
|
|
44
|
-
}
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
const lines = raw.split(/\r?\n/);
|
|
48
|
-
const entries = [];
|
|
49
|
-
for (const line of lines) {
|
|
50
|
-
if (line.trim().length === 0)
|
|
51
|
-
continue;
|
|
52
|
-
let parsed;
|
|
53
|
-
try {
|
|
54
|
-
parsed = JSON.parse(line);
|
|
55
|
-
} catch {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (!isPlainObject(parsed))
|
|
59
|
-
continue;
|
|
60
|
-
if (typeof parsed.ts !== "string")
|
|
61
|
-
continue;
|
|
62
|
-
if (typeof parsed.sessionID !== "string")
|
|
63
|
-
continue;
|
|
64
|
-
if (typeof parsed.agent !== "string")
|
|
65
|
-
continue;
|
|
66
|
-
if (typeof parsed.tool !== "string")
|
|
67
|
-
continue;
|
|
68
|
-
const entry = {
|
|
69
|
-
ts: parsed.ts,
|
|
70
|
-
sessionID: parsed.sessionID,
|
|
71
|
-
agent: parsed.agent,
|
|
72
|
-
tool: parsed.tool
|
|
73
|
-
};
|
|
74
|
-
if (typeof parsed.type === "string") {
|
|
75
|
-
entry.type = parsed.type;
|
|
76
|
-
}
|
|
77
|
-
if (typeof parsed.command === "string") {
|
|
78
|
-
entry.command = parsed.command;
|
|
79
|
-
}
|
|
80
|
-
if (typeof parsed.path === "string") {
|
|
81
|
-
entry.path = parsed.path;
|
|
82
|
-
}
|
|
83
|
-
entries.push(entry);
|
|
84
|
-
}
|
|
85
|
-
if (entries.length === 0) {
|
|
86
|
-
return "No guardrail decisions recorded yet.";
|
|
87
|
-
}
|
|
88
|
-
const blocksOnly = args.includes("--blocks-only");
|
|
89
|
-
const filtered = blocksOnly ? entries.filter(isBlockEntry) : entries;
|
|
90
|
-
if (filtered.length === 0) {
|
|
91
|
-
if (blocksOnly) {
|
|
92
|
-
return "No guardrail block decisions recorded yet.";
|
|
93
|
-
}
|
|
94
|
-
return "No guardrail decisions recorded yet.";
|
|
95
|
-
}
|
|
96
|
-
filtered.sort((a, b) => {
|
|
97
|
-
const diff = b.ts.localeCompare(a.ts);
|
|
98
|
-
return diff === 0 ? 0 : diff;
|
|
99
|
-
});
|
|
100
|
-
const header = blocksOnly ? "# Guardrail Block Log (most-recent-first)" : "# Guardrail Decision Log (most-recent-first)";
|
|
101
|
-
const body = filtered.map(formatEntry).join(`
|
|
102
|
-
`);
|
|
103
|
-
return `${header}
|
|
104
|
-
|
|
105
|
-
${body}`;
|
|
106
|
-
}
|
|
107
|
-
function isPlainObject(value) {
|
|
108
|
-
return typeof value === "object" && value !== null && (value.constructor === Object || Object.getPrototypeOf(value) === null);
|
|
109
|
-
}
|
|
110
|
-
export { handleGuardrailLog };
|