@eyeauras/insight-cli 0.0.0-stage → 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.
- package/.cli-package-build.json +1 -0
- package/LICENSE +21 -0
- package/README.md +54 -2
- package/SKILL.md +55 -0
- package/dist/src/administration-results.d.ts +1 -0
- package/dist/src/administration-results.js +84 -0
- package/dist/src/administration.d.ts +14 -0
- package/dist/src/administration.js +120 -0
- package/dist/src/archive-contract.d.ts +6 -0
- package/dist/src/archive-contract.js +108 -0
- package/dist/src/archive.d.ts +12 -0
- package/dist/src/archive.js +116 -0
- package/dist/src/arguments.d.ts +14 -0
- package/dist/src/arguments.js +62 -0
- package/dist/src/artifacts.d.ts +17 -0
- package/dist/src/artifacts.js +115 -0
- package/dist/src/bin.d.ts +2 -0
- package/dist/src/bin.js +4 -0
- package/dist/src/cli.d.ts +10 -0
- package/dist/src/cli.js +387 -0
- package/dist/src/comment-effects.d.ts +3 -0
- package/dist/src/comment-effects.js +55 -0
- package/dist/src/contexts.d.ts +115 -0
- package/dist/src/contexts.js +1068 -0
- package/dist/src/coordinator.d.ts +41 -0
- package/dist/src/coordinator.js +160 -0
- package/dist/src/cross-results.d.ts +14 -0
- package/dist/src/cross-results.js +71 -0
- package/dist/src/cross.d.ts +3 -0
- package/dist/src/cross.js +43 -0
- package/dist/src/data-effects.d.ts +3 -0
- package/dist/src/data-effects.js +103 -0
- package/dist/src/debugger-results.d.ts +4 -0
- package/dist/src/debugger-results.js +151 -0
- package/dist/src/debugger-supervisor.d.ts +1 -0
- package/dist/src/debugger-supervisor.js +136 -0
- package/dist/src/debugger.d.ts +21 -0
- package/dist/src/debugger.js +267 -0
- package/dist/src/documentation-effects.d.ts +5 -0
- package/dist/src/documentation-effects.js +56 -0
- package/dist/src/extensions.d.ts +64 -0
- package/dist/src/extensions.js +289 -0
- package/dist/src/function-effects.d.ts +4 -0
- package/dist/src/function-effects.js +112 -0
- package/dist/src/ghidra.d.ts +50 -0
- package/dist/src/ghidra.js +468 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +1 -0
- package/dist/src/initial-model.d.ts +6 -0
- package/dist/src/initial-model.js +85 -0
- package/dist/src/json.d.ts +2 -0
- package/dist/src/json.js +8 -0
- package/dist/src/lifecycle.d.ts +49 -0
- package/dist/src/lifecycle.js +148 -0
- package/dist/src/memory-inputs.d.ts +8 -0
- package/dist/src/memory-inputs.js +56 -0
- package/dist/src/merge.d.ts +29 -0
- package/dist/src/merge.js +66 -0
- package/dist/src/model.d.ts +74 -0
- package/dist/src/model.js +67 -0
- package/dist/src/mutation-effects.d.ts +4 -0
- package/dist/src/mutation-effects.js +321 -0
- package/dist/src/mutation-inputs.d.ts +2 -0
- package/dist/src/mutation-inputs.js +71 -0
- package/dist/src/mutations.d.ts +4 -0
- package/dist/src/mutations.js +53 -0
- package/dist/src/native-inputs.d.ts +28 -0
- package/dist/src/native-inputs.js +171 -0
- package/dist/src/native-queries.d.ts +2 -0
- package/dist/src/native-queries.js +29 -0
- package/dist/src/projects.d.ts +31 -0
- package/dist/src/projects.js +301 -0
- package/dist/src/prototype-cli.d.ts +8 -0
- package/dist/src/prototype-cli.js +155 -0
- package/dist/src/queries.d.ts +5 -0
- package/dist/src/queries.js +84 -0
- package/dist/src/query-policy.d.ts +6 -0
- package/dist/src/query-policy.js +72 -0
- package/dist/src/query-results.d.ts +2 -0
- package/dist/src/query-results.js +224 -0
- package/dist/src/research.d.ts +184 -0
- package/dist/src/research.js +808 -0
- package/dist/src/saved-materials.d.ts +12 -0
- package/dist/src/saved-materials.js +196 -0
- package/dist/src/scripts.d.ts +19 -0
- package/dist/src/scripts.js +79 -0
- package/dist/src/sdk-contracts.d.ts +13 -0
- package/dist/src/sdk-contracts.js +37 -0
- package/dist/src/sdk-files.d.ts +29 -0
- package/dist/src/sdk-files.js +249 -0
- package/dist/src/sdk.d.ts +4 -0
- package/dist/src/sdk.js +125 -0
- package/dist/src/server.d.ts +44 -0
- package/dist/src/server.js +455 -0
- package/dist/src/store.d.ts +33 -0
- package/dist/src/store.js +178 -0
- package/dist/src/sync-policy.d.ts +22 -0
- package/dist/src/sync-policy.js +123 -0
- package/dist/src/transport.d.ts +23 -0
- package/dist/src/transport.js +135 -0
- package/dist/src/ui-results.d.ts +2 -0
- package/dist/src/ui-results.js +80 -0
- package/dist/src/ui.d.ts +17 -0
- package/dist/src/ui.js +88 -0
- package/dist/src/utility.d.ts +14 -0
- package/dist/src/utility.js +43 -0
- package/dist/src/version-tracking.d.ts +57 -0
- package/dist/src/version-tracking.js +200 -0
- package/dist/src/workspace.d.ts +199 -0
- package/dist/src/workspace.js +564 -0
- package/package.json +45 -4
- package/references/InsightRepositoryProbe.java +55 -0
- package/references/administration.md +33 -0
- package/references/archive.md +32 -0
- package/references/artifacts.md +47 -0
- package/references/debugger.md +40 -0
- package/references/extensions-and-sync.md +124 -0
- package/references/mutations.json +1424 -0
- package/references/native/InsightApplyDocumentation.java +48 -0
- package/references/native/InsightArchivePayloads.java +36 -0
- package/references/native/InsightBlockTransfer.java +57 -0
- package/references/native/InsightEmulation.java +93 -0
- package/references/native/InsightExtensions.java +36 -0
- package/references/native/InsightFunctionDatabases.java +98 -0
- package/references/native/InsightGuiMain.java +32 -0
- package/references/native/InsightHeadlessMain.java +10 -0
- package/references/native/InsightInitialImport.java +42 -0
- package/references/native/InsightInitialJournal.java +48 -0
- package/references/native/InsightInitialPublication.java +142 -0
- package/references/native/InsightKeytool.java +16 -0
- package/references/native/InsightNativeReceipt.java +31 -0
- package/references/native/InsightPlugins.java +34 -0
- package/references/native/InsightProjectFiles.java +92 -0
- package/references/native/InsightPublicationRecovery.java +63 -0
- package/references/native/InsightPythonWheels.java +31 -0
- package/references/native/InsightResearchQueries.java +188 -0
- package/references/native/InsightSdkFiles.java +142 -0
- package/references/native/InsightSdkScript.java +31 -0
- package/references/native/InsightSdkTools.java +338 -0
- package/references/native/InsightSdkTypes.java +132 -0
- package/references/native/InsightServerAdministration.java +82 -0
- package/references/native/InsightServerInit.java +62 -0
- package/references/native/InsightServerMain.java +43 -0
- package/references/native/InsightServerProbe.java +29 -0
- package/references/native/InsightSnapshotFields.java +68 -0
- package/references/native/InsightSnapshotInspect.java +189 -0
- package/references/native/InsightSnapshotPublisher.java +123 -0
- package/references/native/InsightStartDebugger.java +28 -0
- package/references/native/InsightStopDebugger.java +20 -0
- package/references/native/InsightTraceInspect.java +24 -0
- package/references/native/InsightTraceState.java +130 -0
- package/references/native/InsightTraceTools.java +114 -0
- package/references/native/InsightVersionTracking.java +91 -0
- package/references/native-workflows.md +112 -0
- package/references/queries.json +1761 -0
- package/references/query-semantics.md +96 -0
- package/references/recovery.md +53 -0
- package/references/research.md +101 -0
- package/references/setup.md +47 -0
- package/runtime/GhidraMCP-7.0.0.jar +0 -0
- package/runtime/GhidraMCP-LICENSE +202 -0
- package/runtime/GhidraMCP-NOTICE +10 -0
- package/runtime/provenance.json +11 -0
- package/skills/insight-re/SKILL.md +108 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { command, Permission } from '@eyeauras/cli-factory';
|
|
2
|
+
import { mkdir, readFile, open, rename, realpath, lstat, readdir } from 'node:fs/promises';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { scope, address, number } from './research.js';
|
|
5
|
+
import { id, text, object, fail, stable } from './model.js';
|
|
6
|
+
import { selectedOptions } from './arguments.js';
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
async function persist(path, value) { const temp = path + '.new-' + randomUUID(), file = await open(temp, 'wx', 0o600); try {
|
|
9
|
+
await file.writeFile(stable(value));
|
|
10
|
+
await file.sync();
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
await file.close();
|
|
14
|
+
} await rename(temp, path); }
|
|
15
|
+
/** A native VT object belongs to an existing research session; it is not another agent session. */
|
|
16
|
+
export class VersionTracking {
|
|
17
|
+
workspace;
|
|
18
|
+
research;
|
|
19
|
+
backend;
|
|
20
|
+
tasks;
|
|
21
|
+
constructor(workspace, research, backend, tasks) {
|
|
22
|
+
this.workspace = workspace;
|
|
23
|
+
this.research = research;
|
|
24
|
+
this.backend = backend;
|
|
25
|
+
this.tasks = tasks;
|
|
26
|
+
}
|
|
27
|
+
async ordered(tracking, action) { const key = 'vt:' + tracking, previous = this.tasks.get(key), task = (previous ? previous.catch(() => { }) : Promise.resolve()).then(action); this.tasks.set(key, task); try {
|
|
28
|
+
return await task;
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
if (this.tasks.get(key) === task)
|
|
32
|
+
this.tasks.delete(key);
|
|
33
|
+
} }
|
|
34
|
+
async root(tracking) {
|
|
35
|
+
id(tracking);
|
|
36
|
+
if (!/^vt_a_[a-zA-Z0-9-]+$/.test(tracking))
|
|
37
|
+
fail('invalid', 'Invalid Version Tracking object ID.');
|
|
38
|
+
const root = join(this.workspace.directory, 'version-tracking', tracking);
|
|
39
|
+
if (await realpath(root) !== resolve(root) || (await lstat(root)).isSymbolicLink())
|
|
40
|
+
fail('binding', 'VT object left its owned storage.');
|
|
41
|
+
return root;
|
|
42
|
+
}
|
|
43
|
+
async owner(selected, tracking) {
|
|
44
|
+
const root = await this.root(tracking), owner = object(JSON.parse(await readFile(join(root, 'owner.json'), 'utf8')));
|
|
45
|
+
if (owner.schema !== 1 || owner.tracking !== tracking || owner.profile !== this.workspace.profile || owner.destination.session !== selected.session || owner.destination.target !== selected.target)
|
|
46
|
+
fail('binding', 'VT object belongs to another research scope.');
|
|
47
|
+
await this.workspace.artifacts.verify(owner.sourceSnapshot);
|
|
48
|
+
await this.workspace.artifacts.verify(owner.destinationSnapshot);
|
|
49
|
+
return { root, owner };
|
|
50
|
+
}
|
|
51
|
+
response(owner, value) {
|
|
52
|
+
return { ...owner.destination, tracking: owner.tracking, source: { ...owner.source, snapshotSha256: owner.sourceSnapshot.sha256 }, destination: { ...owner.destination, snapshotSha256: owner.destinationSnapshot.sha256 },
|
|
53
|
+
sourceContextChanged: this.workspace.context(owner.source).generation !== owner.sourceGeneration, destinationContextChanged: this.workspace.context(owner.destination).generation !== owner.destinationGeneration, value };
|
|
54
|
+
}
|
|
55
|
+
async native(operation, root, p) { const backend = await this.backend(); if (!backend.sdkFile)
|
|
56
|
+
fail('configuration', 'Native VT is unavailable.'); return backend.sdkFile('vt.' + operation, { ...p, root }); }
|
|
57
|
+
async list(selected, offset, limit) {
|
|
58
|
+
this.workspace.context(selected);
|
|
59
|
+
const parent = join(this.workspace.directory, 'version-tracking');
|
|
60
|
+
let entries;
|
|
61
|
+
try {
|
|
62
|
+
entries = await readdir(parent, { withFileTypes: true });
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error.code === 'ENOENT')
|
|
66
|
+
return { ...selected, items: [], complete: true };
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
70
|
+
const items = [];
|
|
71
|
+
let index = offset, visited = 0;
|
|
72
|
+
for (; index < entries.length && items.length < limit && visited < 1000; index++, visited++) {
|
|
73
|
+
const entry = entries[index];
|
|
74
|
+
if (!entry.isDirectory() || !/^vt_a_[a-zA-Z0-9-]+$/.test(entry.name))
|
|
75
|
+
fail('binding', 'VT inventory contains an unexpected storage entry.');
|
|
76
|
+
const root = await this.root(entry.name);
|
|
77
|
+
let owner;
|
|
78
|
+
try {
|
|
79
|
+
owner = JSON.parse(await readFile(join(root, 'owner.json'), 'utf8'));
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error.code === 'ENOENT')
|
|
83
|
+
continue;
|
|
84
|
+
fail('binding', 'VT owner record is malformed; retained storage requires inspection.');
|
|
85
|
+
}
|
|
86
|
+
if (owner.profile !== this.workspace.profile || owner.destination.session !== selected.session || owner.destination.target !== selected.target)
|
|
87
|
+
continue;
|
|
88
|
+
items.push({ tracking: entry.name, source: owner.source, destination: owner.destination, sourceSnapshotSha256: owner.sourceSnapshot.sha256, destinationSnapshotSha256: owner.destinationSnapshot.sha256 });
|
|
89
|
+
}
|
|
90
|
+
return { ...selected, items, visited, complete: index === entries.length, ...(index < entries.length ? { nextOffset: index } : {}) };
|
|
91
|
+
}
|
|
92
|
+
decisionResult(request, owner, value) {
|
|
93
|
+
const result = this.response(owner, value);
|
|
94
|
+
if (object(value).state === 'rejected') {
|
|
95
|
+
this.workspace.administrationState(request, 'failed', result);
|
|
96
|
+
fail('rejected', 'Native association constraints rejected this decision; its transaction was rolled back.', result);
|
|
97
|
+
}
|
|
98
|
+
this.workspace.administrationState(request, 'applied', result);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
async create(selected, source, callerId) {
|
|
102
|
+
const reserved = this.workspace.reserveAdministration('sdk.vt.create', { ...selected, source }, callerId), tracking = 'vt_' + reserved.request.id;
|
|
103
|
+
return this.research.paired(selected, source, () => this.ordered(tracking, async () => {
|
|
104
|
+
const request = this.workspace.administration(reserved.request.id);
|
|
105
|
+
if (reserved.replay && request.state !== 'accepted') {
|
|
106
|
+
if (request.state === 'applied')
|
|
107
|
+
return request.result;
|
|
108
|
+
const { root, owner } = await this.owner(selected, tracking);
|
|
109
|
+
let receipt;
|
|
110
|
+
try {
|
|
111
|
+
receipt = object(JSON.parse(await readFile(join(root, 'created.json'), 'utf8')));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
fail('unknown', 'VT creation is retained without a completed receipt; it is not repeated.');
|
|
115
|
+
}
|
|
116
|
+
if (receipt.request !== request.id || receipt.operation !== 'create')
|
|
117
|
+
fail('binding', 'VT creation receipt differs.');
|
|
118
|
+
const result = this.response(owner, receipt.value);
|
|
119
|
+
this.workspace.administrationState(request.id, 'applied', result);
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
const backend = await this.backend();
|
|
123
|
+
await backend.open(selected);
|
|
124
|
+
await backend.open(source);
|
|
125
|
+
const sourceSnapshot = await backend.saved(source), destinationSnapshot = await backend.saved(selected), root = join(this.workspace.directory, 'version-tracking', tracking);
|
|
126
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
127
|
+
if (await realpath(root) !== resolve(root))
|
|
128
|
+
fail('binding', 'VT storage moved.');
|
|
129
|
+
const owner = { schema: 1, tracking, profile: this.workspace.profile, source, destination: selected, sourceSnapshot, destinationSnapshot,
|
|
130
|
+
sourceGeneration: this.workspace.context(source).generation, destinationGeneration: this.workspace.context(selected).generation };
|
|
131
|
+
await persist(join(root, 'owner.json'), owner);
|
|
132
|
+
this.workspace.administrationState(request.id, 'running', { tracking });
|
|
133
|
+
try {
|
|
134
|
+
const value = await this.native('create', root, { request_id: request.id, source_snapshot: await this.workspace.artifacts.verify(sourceSnapshot), destination_snapshot: await this.workspace.artifacts.verify(destinationSnapshot), receipt: join(root, 'created.json') });
|
|
135
|
+
const result = this.response(owner, value);
|
|
136
|
+
this.workspace.administrationState(request.id, 'applied', result);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
this.workspace.administrationState(request.id, 'unknown', { ...selected, tracking, state: 'unknown' });
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
async read(selected, tracking, operation, p) { return this.ordered(tracking, async () => { const { root, owner } = await this.owner(selected, tracking); return this.response(owner, await this.native(operation, root, p)); }); }
|
|
146
|
+
async decide(selected, tracking, p, callerId) {
|
|
147
|
+
const reserved = this.workspace.reserveAdministration('sdk.vt.decide', { ...selected, tracking, ...p }, callerId);
|
|
148
|
+
return this.ordered(tracking, async () => {
|
|
149
|
+
const request = this.workspace.administration(reserved.request.id), { root, owner } = await this.owner(selected, tracking), receipts = join(root, 'decisions');
|
|
150
|
+
await mkdir(receipts, { recursive: true, mode: 0o700 });
|
|
151
|
+
const receiptPath = join(receipts, request.id + '.json');
|
|
152
|
+
if (reserved.replay && request.state !== 'accepted') {
|
|
153
|
+
if (request.state === 'applied')
|
|
154
|
+
return request.result;
|
|
155
|
+
if (request.state === 'failed')
|
|
156
|
+
fail('rejected', 'The native association decision was rejected and is not repeated.', request.result);
|
|
157
|
+
let receipt;
|
|
158
|
+
try {
|
|
159
|
+
receipt = object(JSON.parse(await readFile(receiptPath, 'utf8')));
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
fail('unknown', 'VT decision is uncertain and is not repeated.');
|
|
163
|
+
}
|
|
164
|
+
if (receipt.request !== request.id || receipt.operation !== 'decide')
|
|
165
|
+
fail('binding', 'VT decision receipt differs.');
|
|
166
|
+
return this.decisionResult(request.id, owner, receipt.value);
|
|
167
|
+
}
|
|
168
|
+
if (this.workspace.unresolvedSessionAdministration(selected.session, selected.target).some(earlier => earlier.id !== request.id && object(object(earlier.intent).parameters).tracking === tracking))
|
|
169
|
+
fail('blocked', 'An earlier decision on this VT object is unresolved.');
|
|
170
|
+
this.workspace.administrationState(request.id, 'running', { ...selected, tracking });
|
|
171
|
+
try {
|
|
172
|
+
const value = await this.native('decide', root, { ...p, request_id: request.id, receipt: receiptPath });
|
|
173
|
+
return this.decisionResult(request.id, owner, value);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
if (this.workspace.administration(request.id).state !== 'failed')
|
|
177
|
+
this.workspace.administrationState(request.id, 'unknown', { ...selected, tracking, state: 'unknown' });
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export function trackingCommands(service) {
|
|
184
|
+
const tracking = { flags: '--tracking <id>', description: 'Native VT object returned by create', required: true }, request = { flags: '--request-id <id>', description: 'Retrieve a retained native decision without repeating it' }, association = [{ flags: '--source-address <address>', description: 'Source address in this VT snapshot', required: true }, { flags: '--destination-address <address>', description: 'Destination address in this VT snapshot', required: true }];
|
|
185
|
+
return [command('version-tracking', 'Native source/destination match sets, association decisions and markup inventory', [
|
|
186
|
+
command('list', 'List VT objects owned by this destination research scope, including retained creation stages', ({ options: o }, c) => service(c).list(scope(o), number(o.offset, 1000000), number(o.limit, 1000, 1)), { permission: Permission.ReadOnly, options: [...selectedOptions, { flags: '--limit <count>', description: 'Maximum returned owned VT objects', defaultValue: 100 }, { flags: '--offset <count>', description: 'Inventory offset; use nextOffset after a partial scan', defaultValue: 0 }] }),
|
|
187
|
+
command('create', 'Correlate immutable source/destination snapshots in a persistent owned native VT project', ({ options: o }, c) => {
|
|
188
|
+
const selected = scope(o), source = { session: o.sourceSession === undefined ? selected.session : id(o.sourceSession), target: id(o.sourceTarget) };
|
|
189
|
+
return service(c).create(selected, source, o.requestId === undefined ? undefined : id(o.requestId));
|
|
190
|
+
}, { permission: Permission.Update, options: [...selectedOptions, { flags: '--source-target <id>', description: 'Source immutable target', required: true }, { flags: '--source-session <id>', description: 'Source research session (default destination session)' }, request] }),
|
|
191
|
+
command('matches', 'Read native match sets and correlator-specific scores from the saved VT object', ({ options: o }, c) => service(c).read(scope(o), id(o.tracking), 'matches', { limit: number(o.limit, 1000, 1), offset: number(o.offset, 100000) }), { permission: Permission.ReadOnly, options: [...selectedOptions, tracking, { flags: '--limit <count>', description: 'Match page size 1–1000', defaultValue: 100 }, { flags: '--offset <count>', description: 'Page offset', defaultValue: 0 }] }),
|
|
192
|
+
command('markup', 'Inspect native markup values for one association before agent-directed edits', ({ options: o }, c) => service(c).read(scope(o), id(o.tracking), 'markup', { source_address: address(o.sourceAddress), destination_address: address(o.destinationAddress) }), { permission: Permission.ReadOnly, options: [...selectedOptions, tracking, ...association] }),
|
|
193
|
+
command('decide', 'Explicitly accept/reject/reset one native association; native one-to-one constraints apply', ({ options: o }, c) => {
|
|
194
|
+
const decision = text(o.decision);
|
|
195
|
+
if (!['accepted', 'rejected', 'available'].includes(decision))
|
|
196
|
+
fail('invalid', 'Decision must be accepted, rejected or available.');
|
|
197
|
+
return service(c).decide(scope(o), id(o.tracking), { source_address: address(o.sourceAddress), destination_address: address(o.destinationAddress), decision }, o.requestId === undefined ? undefined : id(o.requestId));
|
|
198
|
+
}, { permission: Permission.Update, options: [...selectedOptions, tracking, ...association, { flags: '--decision <state>', description: 'accepted, rejected or available', required: true }, request] }),
|
|
199
|
+
])];
|
|
200
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { Artifacts, type Artifact } from './artifacts.js';
|
|
2
|
+
export interface ResearchTarget {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
binarySha256: string;
|
|
6
|
+
size: number;
|
|
7
|
+
input: Artifact;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResearchSession {
|
|
11
|
+
id: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GhidraLoadSettings {
|
|
15
|
+
autoAnalyze: boolean;
|
|
16
|
+
language?: string;
|
|
17
|
+
compilerSpec?: string;
|
|
18
|
+
imageBase?: string;
|
|
19
|
+
loader?: string;
|
|
20
|
+
loaderOptions?: Record<string, string | number | boolean>;
|
|
21
|
+
}
|
|
22
|
+
export interface GhidraModel {
|
|
23
|
+
target: string;
|
|
24
|
+
settings: GhidraLoadSettings;
|
|
25
|
+
state: 'opening' | 'ready' | 'unknown';
|
|
26
|
+
sharedRevision?: number;
|
|
27
|
+
sharedSnapshot?: Artifact;
|
|
28
|
+
}
|
|
29
|
+
export interface Scope {
|
|
30
|
+
session: string;
|
|
31
|
+
target: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ScalarChange {
|
|
34
|
+
address: string;
|
|
35
|
+
field: 'function.name' | 'comment.eol' | 'comment.pre' | 'comment.post' | 'comment.plate' | 'comment.repeatable';
|
|
36
|
+
original: string | null;
|
|
37
|
+
local: string | null;
|
|
38
|
+
/** The field ceased to exist in a retained complex program result. Never a scalar setter. */
|
|
39
|
+
removed?: true;
|
|
40
|
+
dependency?: string;
|
|
41
|
+
conflict?: {
|
|
42
|
+
shared: string | null;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface SyncPolicy {
|
|
46
|
+
publish: 'manual' | 'after-edit' | 'after-save';
|
|
47
|
+
refresh: 'manual' | 'before-edit';
|
|
48
|
+
}
|
|
49
|
+
export interface GhidraContext extends Scope {
|
|
50
|
+
/** Internal storage key, never a caller's backend selector. */
|
|
51
|
+
id: string;
|
|
52
|
+
tool: 'ghidra';
|
|
53
|
+
state: 'opening' | 'ready' | 'stopped' | 'needs_recovery';
|
|
54
|
+
generation: number;
|
|
55
|
+
baseRevision?: number;
|
|
56
|
+
baseSnapshot?: Artifact;
|
|
57
|
+
workingSnapshot?: Artifact;
|
|
58
|
+
viewEpoch?: number;
|
|
59
|
+
scalars: ScalarChange[];
|
|
60
|
+
complexChanges: string[];
|
|
61
|
+
debugger?: DebuggerState;
|
|
62
|
+
syncPolicy?: SyncPolicy;
|
|
63
|
+
}
|
|
64
|
+
export interface SavedTrace {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
snapshot: Artifact;
|
|
68
|
+
snap: string;
|
|
69
|
+
modules: number;
|
|
70
|
+
threads: number;
|
|
71
|
+
connected: boolean;
|
|
72
|
+
thread?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface DebuggerState {
|
|
75
|
+
traces: SavedTrace[];
|
|
76
|
+
active?: string;
|
|
77
|
+
connected: boolean;
|
|
78
|
+
}
|
|
79
|
+
export type RequestState = 'accepted' | 'running' | 'applied' | 'failed' | 'unknown';
|
|
80
|
+
export interface AdministrationRequest {
|
|
81
|
+
id: string;
|
|
82
|
+
operation: string;
|
|
83
|
+
intent: unknown;
|
|
84
|
+
state: RequestState;
|
|
85
|
+
callerId?: string;
|
|
86
|
+
result?: unknown;
|
|
87
|
+
createdAt: string;
|
|
88
|
+
updatedAt: string;
|
|
89
|
+
}
|
|
90
|
+
export interface ResearchRequest {
|
|
91
|
+
id: string;
|
|
92
|
+
callerId?: string;
|
|
93
|
+
operation: string;
|
|
94
|
+
intent: unknown;
|
|
95
|
+
context: string;
|
|
96
|
+
state: RequestState;
|
|
97
|
+
result?: unknown;
|
|
98
|
+
execution?: unknown;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
updatedAt: string;
|
|
101
|
+
}
|
|
102
|
+
export interface Publication extends Scope {
|
|
103
|
+
id: string;
|
|
104
|
+
request: string;
|
|
105
|
+
state: 'preparing' | 'commit_intent' | 'unknown' | 'verified' | 'conflict';
|
|
106
|
+
expectedRevision: number;
|
|
107
|
+
snapshot: Artifact;
|
|
108
|
+
generation: number;
|
|
109
|
+
scalars: ScalarChange[];
|
|
110
|
+
complex: boolean;
|
|
111
|
+
complexChanges?: string[];
|
|
112
|
+
publishedRevision?: number;
|
|
113
|
+
detail?: unknown;
|
|
114
|
+
}
|
|
115
|
+
export interface OpenReservation {
|
|
116
|
+
context: GhidraContext;
|
|
117
|
+
request: ResearchRequest;
|
|
118
|
+
replay: boolean;
|
|
119
|
+
}
|
|
120
|
+
type ContextPatch = Partial<Pick<GhidraContext, 'state' | 'baseRevision' | 'baseSnapshot' | 'workingSnapshot' | 'viewEpoch' | 'scalars' | 'complexChanges' | 'debugger' | 'syncPolicy'>>;
|
|
121
|
+
/** Profile root state, deliberately separate from the earlier coordinator.sqlite journals. */
|
|
122
|
+
export declare class Workspace {
|
|
123
|
+
readonly profile: string;
|
|
124
|
+
readonly directory: string;
|
|
125
|
+
readonly artifacts: Artifacts;
|
|
126
|
+
private readonly db;
|
|
127
|
+
private namespace;
|
|
128
|
+
constructor(directory: string, profile: string);
|
|
129
|
+
close(): void;
|
|
130
|
+
private transaction;
|
|
131
|
+
private rememberArtifact;
|
|
132
|
+
private knownSnapshot;
|
|
133
|
+
captureSnapshot(path: string): Promise<Artifact>;
|
|
134
|
+
importTarget(path: string): Promise<ResearchTarget>;
|
|
135
|
+
target(target: string): ResearchTarget;
|
|
136
|
+
targets(limit?: number, offset?: number): ResearchTarget[];
|
|
137
|
+
session(session: string): ResearchSession;
|
|
138
|
+
sessions(limit?: number, offset?: number): ResearchSession[];
|
|
139
|
+
model(target: string): GhidraModel;
|
|
140
|
+
context(scope: Scope): GhidraContext;
|
|
141
|
+
contexts(session: string, limit?: number, offset?: number): GhidraContext[];
|
|
142
|
+
private existingRequest;
|
|
143
|
+
private insertRequest;
|
|
144
|
+
reserveOpen(target: string, session: string | 'new', settings: GhidraLoadSettings, callerId?: string, mode?: 'headless' | 'gui'): OpenReservation;
|
|
145
|
+
reserveRequest(scope: Scope, operation: string, parameters: unknown, callerId?: string): {
|
|
146
|
+
request: ResearchRequest;
|
|
147
|
+
replay: boolean;
|
|
148
|
+
};
|
|
149
|
+
request(request: string): ResearchRequest;
|
|
150
|
+
reserveAdministration(operation: string, parameters: unknown, callerId?: string): {
|
|
151
|
+
request: AdministrationRequest;
|
|
152
|
+
replay: boolean;
|
|
153
|
+
};
|
|
154
|
+
administrationByCaller(callerId: string): AdministrationRequest | undefined;
|
|
155
|
+
requestByCaller(callerId: string): ResearchRequest | undefined;
|
|
156
|
+
administration(request: string): AdministrationRequest;
|
|
157
|
+
unresolvedAdministration(): AdministrationRequest[];
|
|
158
|
+
unresolvedSessionAdministration(session: string, target?: string): AdministrationRequest[];
|
|
159
|
+
unresolvedServer(): AdministrationRequest[];
|
|
160
|
+
unresolvedProject(project: string): AdministrationRequest[];
|
|
161
|
+
administrationState(request: string, state: Exclude<RequestState, 'accepted'>, result?: unknown): AdministrationRequest;
|
|
162
|
+
unresolved(scope: Scope): ResearchRequest[];
|
|
163
|
+
startRequest(request: string, execution?: unknown): ResearchRequest;
|
|
164
|
+
recordRequest(request: string, state: 'applied' | 'failed' | 'unknown', result: unknown): ResearchRequest;
|
|
165
|
+
private writeRequest;
|
|
166
|
+
establishModel(target: string, revision: number, snapshot: Artifact): GhidraModel;
|
|
167
|
+
beginModelInitialization(target: string): GhidraModel;
|
|
168
|
+
observeShared(target: string, revision: number, snapshot: Artifact): GhidraModel;
|
|
169
|
+
publication(publication: string): Publication;
|
|
170
|
+
activePublication(target: string): Publication | undefined;
|
|
171
|
+
beginPublication(scope: Scope, request: string, expectedRevision: number, snapshot: Artifact): Publication;
|
|
172
|
+
publicationIntent(publication: string): Publication;
|
|
173
|
+
unknownPublication(publication: string, detail: unknown): {
|
|
174
|
+
state: "unknown";
|
|
175
|
+
detail: unknown;
|
|
176
|
+
id: string;
|
|
177
|
+
request: string;
|
|
178
|
+
expectedRevision: number;
|
|
179
|
+
snapshot: Artifact;
|
|
180
|
+
generation: number;
|
|
181
|
+
scalars: ScalarChange[];
|
|
182
|
+
complex: boolean;
|
|
183
|
+
complexChanges?: string[];
|
|
184
|
+
publishedRevision?: number;
|
|
185
|
+
session: string;
|
|
186
|
+
target: string;
|
|
187
|
+
};
|
|
188
|
+
finishPublication(publication: string, publishedRevision: number, result: unknown): Publication;
|
|
189
|
+
rejectPublication(publication: string, result: unknown): Publication;
|
|
190
|
+
publishedSince(target: string, revision: number): Publication[];
|
|
191
|
+
saveContext(scope: Scope, expectedGeneration: number, patch: ContextPatch): GhidraContext;
|
|
192
|
+
/** Snapshot and successful request acknowledgment enter the same durable transaction. */
|
|
193
|
+
completeSavedRequest(scope: Scope, request: string, expectedGeneration: number, patch: ContextPatch, result: unknown): {
|
|
194
|
+
context: GhidraContext;
|
|
195
|
+
request: ResearchRequest;
|
|
196
|
+
};
|
|
197
|
+
private writeContext;
|
|
198
|
+
}
|
|
199
|
+
export {};
|