yam-flow 2.2.1 → 2.3.1
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/AGENTS.md +18 -0
- package/CHANGELOG.md +36 -0
- package/COMMANDS.md +8 -1
- package/README.md +18 -12
- package/ROADMAP.md +27 -0
- package/dist/bin/yam.js +293 -111
- package/dist/lib/skill-installation.d.ts +76 -0
- package/dist/lib/skill-installation.js +554 -0
- package/dist/lib/trust-kernel.d.ts +54 -0
- package/dist/lib/trust-kernel.js +194 -0
- package/dist/lib/ueye-artifacts.d.ts +98 -0
- package/dist/lib/ueye-artifacts.js +317 -0
- package/package.json +3 -2
- package/references/final-report.md +2 -0
- package/references/honest-completion.md +1 -0
- package/references/mission.md +16 -0
- package/references/tool-trust-layer.md +3 -0
- package/references/trust-kernel.md +3 -0
- package/references/truth-matrix.md +2 -0
- package/references/ueye-proof.md +6 -0
- package/references/ueye.md +12 -0
- package/references/verification-levels.md +2 -1
- package/skills/mission/SKILL.md +19 -4
- package/skills/ueye/SKILL.md +11 -0
- package/src/bin/yam.ts +282 -106
- package/src/lib/skill-installation.ts +638 -0
- package/src/lib/trust-kernel.ts +239 -0
- package/src/lib/ueye-artifacts.ts +354 -0
- package/templates/mission-plan.md +25 -2
- package/templates/ueye-comparison.md +12 -0
- package/templates/ueye-review.md +26 -0
- package/yam.manifest.json +6 -5
|
@@ -9,6 +9,10 @@ export type LoopStageStatus = 'passed' | 'failed' | 'blocked' | 'skipped' | 'par
|
|
|
9
9
|
export type LoopEvidenceLevel = 'none' | 'fixture' | 'smoke' | 'local' | 'real';
|
|
10
10
|
export type ToolIntent = 'read_only' | 'write' | 'destructive' | 'runtime' | 'visual' | 'publish';
|
|
11
11
|
export type ReadinessState = 'usable' | 'degraded' | 'blocked' | 'unknown';
|
|
12
|
+
export type MissionLaneRole = 'implementer' | 'reviewer' | 'ux_verifier' | 'doctor' | 'other';
|
|
13
|
+
export type MissionAccessMode = 'read_only' | 'write';
|
|
14
|
+
export type MissionLifecycleStatus = 'pending' | 'running' | 'stopped' | 'failed' | 'cancelled';
|
|
15
|
+
export type MissionOutcome = 'passed' | 'failed' | 'blocked' | 'ambiguous';
|
|
12
16
|
export interface SafetyHit {
|
|
13
17
|
level: SafetyLevel;
|
|
14
18
|
reason: string;
|
|
@@ -110,6 +114,50 @@ export interface MissionPatchEnvelope {
|
|
|
110
114
|
rollback_hint: RollbackHint;
|
|
111
115
|
truth_status: TruthStatus;
|
|
112
116
|
}
|
|
117
|
+
export interface MissionContractCheck {
|
|
118
|
+
id: string;
|
|
119
|
+
label: string;
|
|
120
|
+
status: 'pass' | 'fail' | 'warning';
|
|
121
|
+
next_action: string;
|
|
122
|
+
}
|
|
123
|
+
export interface MissionSubagentReceipt {
|
|
124
|
+
schema: 'yam.mission-subagent-receipt.v1';
|
|
125
|
+
receipt_id: string;
|
|
126
|
+
generated_at: string;
|
|
127
|
+
thread_id: string;
|
|
128
|
+
lane_id: string;
|
|
129
|
+
agent_id: string;
|
|
130
|
+
role: MissionLaneRole;
|
|
131
|
+
access_mode: MissionAccessMode;
|
|
132
|
+
lifecycle_status: MissionLifecycleStatus;
|
|
133
|
+
outcome: MissionOutcome;
|
|
134
|
+
assigned_scope: string;
|
|
135
|
+
changed_files: string[];
|
|
136
|
+
verification_evidence: string[];
|
|
137
|
+
remaining_risks: string[];
|
|
138
|
+
checks: MissionContractCheck[];
|
|
139
|
+
blockers: string[];
|
|
140
|
+
warnings: string[];
|
|
141
|
+
completion_eligible: boolean;
|
|
142
|
+
truth_status: TruthStatus;
|
|
143
|
+
}
|
|
144
|
+
export interface MissionCompletionGate {
|
|
145
|
+
schema: 'yam.mission-completion-gate.v1';
|
|
146
|
+
generated_at: string;
|
|
147
|
+
expected_thread_ids: string[];
|
|
148
|
+
receipt_count: number;
|
|
149
|
+
receipts: MissionSubagentReceipt[];
|
|
150
|
+
missing_thread_ids: string[];
|
|
151
|
+
duplicate_thread_ids: string[];
|
|
152
|
+
unexpected_thread_ids: string[];
|
|
153
|
+
invalid_thread_ids: string[];
|
|
154
|
+
read_only_violations: string[];
|
|
155
|
+
blockers: string[];
|
|
156
|
+
warnings: string[];
|
|
157
|
+
ready_to_claim_complete: boolean;
|
|
158
|
+
next_action: string;
|
|
159
|
+
truth_status: TruthStatus;
|
|
160
|
+
}
|
|
113
161
|
export interface RuntimeBackendEvidence {
|
|
114
162
|
schema: 'yam.runtime-backend-evidence.v1';
|
|
115
163
|
backend: RuntimeBackend;
|
|
@@ -266,6 +314,8 @@ export interface ProofSummary {
|
|
|
266
314
|
unverified?: unknown;
|
|
267
315
|
visualProvenance?: unknown;
|
|
268
316
|
missionEnvelope?: unknown;
|
|
317
|
+
missionReceipt?: unknown;
|
|
318
|
+
missionCompletion?: unknown;
|
|
269
319
|
rollbackHint?: unknown;
|
|
270
320
|
runtimeBackendEvidence?: unknown;
|
|
271
321
|
mediaProof?: unknown;
|
|
@@ -299,6 +349,8 @@ export interface YamCompletionProof {
|
|
|
299
349
|
runtime: string[];
|
|
300
350
|
visualProvenance: string[];
|
|
301
351
|
missionEnvelope: string[];
|
|
352
|
+
missionReceipt: string[];
|
|
353
|
+
missionCompletion: string[];
|
|
302
354
|
rollbackHint: string[];
|
|
303
355
|
runtimeBackendEvidence: string[];
|
|
304
356
|
mediaProof: string[];
|
|
@@ -319,6 +371,8 @@ export declare function buildUeyeSurfaceContext(input?: Partial<UeyeSurfaceConte
|
|
|
319
371
|
export declare function buildUeyeDesignCompletionGate(input?: Partial<UeyeDesignCompletionGate> & Record<string, unknown>): UeyeDesignCompletionGate;
|
|
320
372
|
export declare function buildRollbackHint(input?: Partial<RollbackHint>): RollbackHint;
|
|
321
373
|
export declare function buildMissionPatchEnvelope(input?: Partial<MissionPatchEnvelope>): MissionPatchEnvelope;
|
|
374
|
+
export declare function buildMissionSubagentReceipt(input?: Partial<MissionSubagentReceipt> & Record<string, unknown>): MissionSubagentReceipt;
|
|
375
|
+
export declare function buildMissionCompletionGate(input?: Partial<MissionCompletionGate> & Record<string, unknown>): MissionCompletionGate;
|
|
322
376
|
export declare function buildRuntimeBackendEvidence(input?: Partial<RuntimeBackendEvidence>): RuntimeBackendEvidence;
|
|
323
377
|
export declare function buildStudyNote(input?: Partial<StudyNote> & Record<string, unknown>): StudyNote;
|
|
324
378
|
export declare function buildLoopReport(input?: Partial<LoopReport> & Record<string, unknown>): LoopReport;
|
package/dist/lib/trust-kernel.js
CHANGED
|
@@ -162,6 +162,142 @@ export function buildMissionPatchEnvelope(input = {}) {
|
|
|
162
162
|
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : 'partial'
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
|
+
export function buildMissionSubagentReceipt(input = {}) {
|
|
166
|
+
const role = normalizeMissionLaneRole(input.role);
|
|
167
|
+
const accessMode = normalizeMissionAccessMode(input.access_mode, role);
|
|
168
|
+
const lifecycleStatus = normalizeMissionLifecycleStatus(input.lifecycle_status);
|
|
169
|
+
const outcome = normalizeMissionOutcome(input.outcome);
|
|
170
|
+
const threadId = String(input.thread_id || '');
|
|
171
|
+
const assignedScope = String(input.assigned_scope || '');
|
|
172
|
+
const changedFiles = asList(input.changed_files);
|
|
173
|
+
const verificationEvidence = asList(input.verification_evidence);
|
|
174
|
+
const remainingRisks = asList(input.remaining_risks);
|
|
175
|
+
const readOnlyRole = role === 'reviewer' || role === 'doctor';
|
|
176
|
+
const checks = [
|
|
177
|
+
missionContractCheck('thread_id', 'Thread id is recorded', Boolean(threadId), 'record --thread-id for every spawned thread'),
|
|
178
|
+
missionContractCheck('assigned_scope', 'Assigned scope is recorded', Boolean(assignedScope), 'record the bounded lane scope'),
|
|
179
|
+
missionContractCheck('read_only_role', 'Reviewer and doctor lanes stay read-only', !readOnlyRole || (accessMode === 'read_only' && changedFiles.length === 0), 'rerun reviewer/doctor without write access or changed files'),
|
|
180
|
+
missionContractCheck('terminal_lifecycle', 'Lifecycle reached a terminal state', ['stopped', 'failed', 'cancelled'].includes(lifecycleStatus), 'wait for a terminal lifecycle event before finalization'),
|
|
181
|
+
missionContractCheck('explicit_outcome', 'Outcome is explicit and unambiguous', outcome !== 'ambiguous', 'record passed, failed, or blocked; a stop event alone is not success evidence'),
|
|
182
|
+
missionContractCheck('passed_evidence', 'Passed outcome has verification evidence', outcome !== 'passed' || verificationEvidence.length > 0, 'attach at least one concrete verification item for a passed outcome')
|
|
183
|
+
];
|
|
184
|
+
const blockers = checks.filter((check) => check.status === 'fail').map((check) => `${check.id}: ${check.next_action}`);
|
|
185
|
+
if (outcome === 'failed' || outcome === 'blocked')
|
|
186
|
+
blockers.push(`outcome_${outcome}: resolve or hand off this thread before mission completion`);
|
|
187
|
+
if ((lifecycleStatus === 'failed' || lifecycleStatus === 'cancelled') && outcome === 'passed') {
|
|
188
|
+
blockers.push('lifecycle_outcome_conflict: a failed or cancelled lifecycle cannot claim a passed outcome');
|
|
189
|
+
}
|
|
190
|
+
const warnings = remainingRisks.length ? ['remaining risks are recorded and must be included in the mission handoff'] : [];
|
|
191
|
+
const completionEligible = blockers.length === 0 && lifecycleStatus === 'stopped' && outcome === 'passed';
|
|
192
|
+
const truth = completionEligible ? 'verified' : blockers.length ? 'blocked' : 'partial';
|
|
193
|
+
return {
|
|
194
|
+
schema: 'yam.mission-subagent-receipt.v1',
|
|
195
|
+
receipt_id: String(input.receipt_id || `receipt-${threadId || 'unassigned'}`),
|
|
196
|
+
generated_at: String(input.generated_at || new Date().toISOString()),
|
|
197
|
+
thread_id: threadId,
|
|
198
|
+
lane_id: String(input.lane_id || threadId),
|
|
199
|
+
agent_id: String(input.agent_id || ''),
|
|
200
|
+
role,
|
|
201
|
+
access_mode: accessMode,
|
|
202
|
+
lifecycle_status: lifecycleStatus,
|
|
203
|
+
outcome,
|
|
204
|
+
assigned_scope: assignedScope,
|
|
205
|
+
changed_files: changedFiles,
|
|
206
|
+
verification_evidence: verificationEvidence,
|
|
207
|
+
remaining_risks: remainingRisks,
|
|
208
|
+
checks,
|
|
209
|
+
blockers: uniqueStrings(blockers),
|
|
210
|
+
warnings,
|
|
211
|
+
completion_eligible: completionEligible,
|
|
212
|
+
truth_status: truth
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export function buildMissionCompletionGate(input = {}) {
|
|
216
|
+
const expectedThreadIds = uniqueStrings(asList(input.expected_thread_ids));
|
|
217
|
+
const receipts = asObjectList(input.receipts).map((receipt) => buildMissionSubagentReceipt(receipt));
|
|
218
|
+
const receiptCounts = new Map();
|
|
219
|
+
for (const receipt of receipts) {
|
|
220
|
+
receiptCounts.set(receipt.thread_id, (receiptCounts.get(receipt.thread_id) || 0) + 1);
|
|
221
|
+
}
|
|
222
|
+
const missingThreadIds = expectedThreadIds.filter((threadId) => !receiptCounts.has(threadId));
|
|
223
|
+
const duplicateThreadIds = [...receiptCounts.entries()].filter(([, count]) => count > 1).map(([threadId]) => threadId).filter(Boolean);
|
|
224
|
+
const unexpectedThreadIds = uniqueStrings(receipts.map((receipt) => receipt.thread_id).filter((threadId) => threadId && !expectedThreadIds.includes(threadId)));
|
|
225
|
+
const expectedReceipts = receipts.filter((receipt) => expectedThreadIds.includes(receipt.thread_id));
|
|
226
|
+
const invalidThreadIds = uniqueStrings([
|
|
227
|
+
...expectedReceipts.filter((receipt) => !receipt.completion_eligible).map((receipt) => receipt.thread_id),
|
|
228
|
+
...receipts.filter((receipt) => !receipt.thread_id).map((receipt) => `missing:${receipt.receipt_id}`)
|
|
229
|
+
]);
|
|
230
|
+
const readOnlyViolations = uniqueStrings(receipts
|
|
231
|
+
.filter((receipt) => receipt.checks.some((check) => check.id === 'read_only_role' && check.status === 'fail'))
|
|
232
|
+
.map((receipt) => receipt.thread_id || receipt.lane_id));
|
|
233
|
+
const blockers = [];
|
|
234
|
+
if (!expectedThreadIds.length)
|
|
235
|
+
blockers.push('expected_thread_inventory_missing: record every spawned thread before finalization');
|
|
236
|
+
if (missingThreadIds.length)
|
|
237
|
+
blockers.push(`missing_receipts: ${missingThreadIds.join(', ')}`);
|
|
238
|
+
if (duplicateThreadIds.length)
|
|
239
|
+
blockers.push(`duplicate_receipts: ${duplicateThreadIds.join(', ')}`);
|
|
240
|
+
if (unexpectedThreadIds.length)
|
|
241
|
+
blockers.push(`unexpected_receipts: ${unexpectedThreadIds.join(', ')}`);
|
|
242
|
+
if (invalidThreadIds.length)
|
|
243
|
+
blockers.push(`invalid_or_incomplete_receipts: ${invalidThreadIds.join(', ')}`);
|
|
244
|
+
if (readOnlyViolations.length)
|
|
245
|
+
blockers.push(`read_only_contract_violations: ${readOnlyViolations.join(', ')}`);
|
|
246
|
+
blockers.push(...asList(input.blockers));
|
|
247
|
+
const warnings = uniqueStrings(asList(input.warnings));
|
|
248
|
+
const ready = blockers.length === 0 && expectedReceipts.length === expectedThreadIds.length;
|
|
249
|
+
return {
|
|
250
|
+
schema: 'yam.mission-completion-gate.v1',
|
|
251
|
+
generated_at: String(input.generated_at || new Date().toISOString()),
|
|
252
|
+
expected_thread_ids: expectedThreadIds,
|
|
253
|
+
receipt_count: receipts.length,
|
|
254
|
+
receipts,
|
|
255
|
+
missing_thread_ids: missingThreadIds,
|
|
256
|
+
duplicate_thread_ids: duplicateThreadIds,
|
|
257
|
+
unexpected_thread_ids: unexpectedThreadIds,
|
|
258
|
+
invalid_thread_ids: invalidThreadIds,
|
|
259
|
+
read_only_violations: readOnlyViolations,
|
|
260
|
+
blockers: uniqueStrings(blockers),
|
|
261
|
+
warnings,
|
|
262
|
+
ready_to_claim_complete: ready,
|
|
263
|
+
next_action: ready ? 'attach this gate to the mission proof summary' : blockers[0] || 'resolve mission receipt warnings',
|
|
264
|
+
truth_status: ready ? 'verified' : 'blocked'
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function missionContractCheck(id, label, passed, nextAction) {
|
|
268
|
+
return {
|
|
269
|
+
id,
|
|
270
|
+
label,
|
|
271
|
+
status: passed ? 'pass' : 'fail',
|
|
272
|
+
next_action: nextAction
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function normalizeMissionLaneRole(value = '') {
|
|
276
|
+
const text = String(value || '').toLowerCase().replace(/[- ]/g, '_');
|
|
277
|
+
if (['implementer', 'reviewer', 'ux_verifier', 'doctor'].includes(text))
|
|
278
|
+
return text;
|
|
279
|
+
return 'other';
|
|
280
|
+
}
|
|
281
|
+
function normalizeMissionAccessMode(value = '', role = 'other') {
|
|
282
|
+
const text = String(value || '').toLowerCase().replace(/[- ]/g, '_');
|
|
283
|
+
if (text === 'read_only' || text === 'readonly')
|
|
284
|
+
return 'read_only';
|
|
285
|
+
if (text === 'write')
|
|
286
|
+
return 'write';
|
|
287
|
+
return role === 'reviewer' || role === 'doctor' ? 'read_only' : 'write';
|
|
288
|
+
}
|
|
289
|
+
function normalizeMissionLifecycleStatus(value = '') {
|
|
290
|
+
const text = String(value || '').toLowerCase();
|
|
291
|
+
if (['pending', 'running', 'stopped', 'failed', 'cancelled'].includes(text))
|
|
292
|
+
return text;
|
|
293
|
+
return 'pending';
|
|
294
|
+
}
|
|
295
|
+
function normalizeMissionOutcome(value = '') {
|
|
296
|
+
const text = String(value || '').toLowerCase();
|
|
297
|
+
if (['passed', 'failed', 'blocked'].includes(text))
|
|
298
|
+
return text;
|
|
299
|
+
return 'ambiguous';
|
|
300
|
+
}
|
|
165
301
|
export function buildRuntimeBackendEvidence(input = {}) {
|
|
166
302
|
const backend = normalizeRuntimeBackend(input.backend);
|
|
167
303
|
const claim = normalizeRuntimeClaim(input.claim);
|
|
@@ -661,6 +797,12 @@ export function classifyEvidenceTruth(summary = {}, options = {}) {
|
|
|
661
797
|
for (const envelope of asList(summary.missionEnvelope)) {
|
|
662
798
|
rows.push(evidenceRow('evidence', envelope, metadataTruth(envelope, 'partial')));
|
|
663
799
|
}
|
|
800
|
+
for (const receipt of asList(summary.missionReceipt)) {
|
|
801
|
+
rows.push(evidenceRow('evidence', receipt, metadataTruth(receipt, 'partial')));
|
|
802
|
+
}
|
|
803
|
+
for (const completion of asList(summary.missionCompletion)) {
|
|
804
|
+
rows.push(evidenceRow('evidence', completion, metadataTruth(completion, 'partial')));
|
|
805
|
+
}
|
|
664
806
|
for (const rollback of asList(summary.rollbackHint)) {
|
|
665
807
|
rows.push(evidenceRow('evidence', rollback, metadataTruth(rollback, 'partial')));
|
|
666
808
|
}
|
|
@@ -715,6 +857,22 @@ export function applyProofTruthCaps(summary = {}, options = {}) {
|
|
|
715
857
|
unverified.push('ueye_design_completion_not_verified');
|
|
716
858
|
}
|
|
717
859
|
}
|
|
860
|
+
const missionRoute = String(summary.route || '').replace(/^\$/, '').toLowerCase() === 'mission';
|
|
861
|
+
const missionCompletionValues = asValueList(summary.missionCompletion);
|
|
862
|
+
if (missionRoute && ['verified', 'proven'].includes(requested)) {
|
|
863
|
+
if (!missionCompletionValues.length) {
|
|
864
|
+
cappedTruth = weakestTruth(cappedTruth, 'partial');
|
|
865
|
+
unverified.push('mission_completion_gate_missing');
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
const missionTruth = missionCompletionCap(missionCompletionValues);
|
|
869
|
+
cappedTruth = weakestTruth(cappedTruth, missionTruth);
|
|
870
|
+
if (missionTruth === 'blocked')
|
|
871
|
+
blockers.push('mission_completion_gate_blocked');
|
|
872
|
+
if (!['verified', 'proven'].includes(missionTruth))
|
|
873
|
+
unverified.push('mission_completion_not_verified');
|
|
874
|
+
}
|
|
875
|
+
}
|
|
718
876
|
if (requested !== cappedTruth) {
|
|
719
877
|
caps.push(`requested ${requested} capped to ${cappedTruth} by evidence`);
|
|
720
878
|
}
|
|
@@ -769,6 +927,8 @@ export function buildYamCompletionProof(summary = {}, options = {}) {
|
|
|
769
927
|
runtime: asList(summary.runtime),
|
|
770
928
|
visualProvenance: asList(summary.visualProvenance),
|
|
771
929
|
missionEnvelope: asList(summary.missionEnvelope),
|
|
930
|
+
missionReceipt: asList(summary.missionReceipt),
|
|
931
|
+
missionCompletion: asList(summary.missionCompletion),
|
|
772
932
|
rollbackHint: asList(summary.rollbackHint),
|
|
773
933
|
runtimeBackendEvidence: asList(summary.runtimeBackendEvidence),
|
|
774
934
|
mediaProof: asList(summary.mediaProof),
|
|
@@ -854,6 +1014,18 @@ function designCompletionCap(value = '') {
|
|
|
854
1014
|
return null;
|
|
855
1015
|
return items.reduce((weakest, item) => weakestTruth(weakest, readStructuredTruth(item, 'partial')), 'proven');
|
|
856
1016
|
}
|
|
1017
|
+
function missionCompletionCap(value = '') {
|
|
1018
|
+
const items = asValueList(value);
|
|
1019
|
+
if (!items.length)
|
|
1020
|
+
return 'partial';
|
|
1021
|
+
return items.reduce((weakest, item) => {
|
|
1022
|
+
const parsed = parseStructuredValue(item);
|
|
1023
|
+
if (!parsed || typeof parsed !== 'object')
|
|
1024
|
+
return weakestTruth(weakest, 'blocked');
|
|
1025
|
+
const gate = buildMissionCompletionGate(parsed);
|
|
1026
|
+
return weakestTruth(weakest, gate.truth_status);
|
|
1027
|
+
}, 'proven');
|
|
1028
|
+
}
|
|
857
1029
|
function strongestSupportedTruth(rows = []) {
|
|
858
1030
|
if (rows.some((row) => row.truth === 'blocked'))
|
|
859
1031
|
return 'blocked';
|
|
@@ -977,6 +1149,28 @@ function asList(value) {
|
|
|
977
1149
|
return [];
|
|
978
1150
|
return Array.isArray(value) ? value.filter(Boolean).map(String) : [String(value)].filter(Boolean);
|
|
979
1151
|
}
|
|
1152
|
+
function asValueList(value) {
|
|
1153
|
+
if (value === undefined || value === null || value === '')
|
|
1154
|
+
return [];
|
|
1155
|
+
return Array.isArray(value) ? value.filter(Boolean) : [value];
|
|
1156
|
+
}
|
|
1157
|
+
function parseStructuredValue(value) {
|
|
1158
|
+
if (value && typeof value === 'object')
|
|
1159
|
+
return value;
|
|
1160
|
+
try {
|
|
1161
|
+
const parsed = JSON.parse(String(value || ''));
|
|
1162
|
+
return parsed && typeof parsed === 'object' ? parsed : null;
|
|
1163
|
+
}
|
|
1164
|
+
catch {
|
|
1165
|
+
return null;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
function asObjectList(value) {
|
|
1169
|
+
if (!value)
|
|
1170
|
+
return [];
|
|
1171
|
+
const items = Array.isArray(value) ? value : [value];
|
|
1172
|
+
return items.filter((item) => Boolean(item) && typeof item === 'object');
|
|
1173
|
+
}
|
|
980
1174
|
function uniqueStrings(values = []) {
|
|
981
1175
|
return [...new Set(values.filter(Boolean).map(String))];
|
|
982
1176
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export interface InspectedImageFile {
|
|
2
|
+
path: string;
|
|
3
|
+
sha256: string;
|
|
4
|
+
bytes: number;
|
|
5
|
+
dimensions: string;
|
|
6
|
+
}
|
|
7
|
+
export interface UeyeAssetEntry {
|
|
8
|
+
id: string;
|
|
9
|
+
file_path: string;
|
|
10
|
+
source_url: string;
|
|
11
|
+
source_page_url: string;
|
|
12
|
+
retrieved_at: string;
|
|
13
|
+
license_note: string;
|
|
14
|
+
operator_provided: boolean;
|
|
15
|
+
do_not_replace: boolean;
|
|
16
|
+
allowed_for_edit: boolean;
|
|
17
|
+
sha256: string;
|
|
18
|
+
bytes: number;
|
|
19
|
+
dimensions: string;
|
|
20
|
+
}
|
|
21
|
+
export interface UeyeAssetManifest {
|
|
22
|
+
schema: 'yam.ueye-asset-manifest.v1';
|
|
23
|
+
updated_at: string;
|
|
24
|
+
assets: UeyeAssetEntry[];
|
|
25
|
+
}
|
|
26
|
+
export interface UeyeRevisionEntry {
|
|
27
|
+
artifact_id: string;
|
|
28
|
+
round: number;
|
|
29
|
+
source_path: string;
|
|
30
|
+
archived_path: string;
|
|
31
|
+
archived_at: string;
|
|
32
|
+
sha256: string;
|
|
33
|
+
bytes: number;
|
|
34
|
+
dimensions: string;
|
|
35
|
+
}
|
|
36
|
+
export interface UeyeRevisionHistory {
|
|
37
|
+
schema: 'yam.ueye-revision-history.v1';
|
|
38
|
+
updated_at: string;
|
|
39
|
+
revisions: UeyeRevisionEntry[];
|
|
40
|
+
}
|
|
41
|
+
export declare function inspectImageFile(file: string): Promise<InspectedImageFile>;
|
|
42
|
+
export declare function upsertUeyeAsset(input: {
|
|
43
|
+
manifest_path: string;
|
|
44
|
+
id: string;
|
|
45
|
+
file: string;
|
|
46
|
+
source_url?: string;
|
|
47
|
+
source_page_url?: string;
|
|
48
|
+
retrieved_at?: string;
|
|
49
|
+
license_note?: string;
|
|
50
|
+
operator_provided?: boolean;
|
|
51
|
+
do_not_replace?: boolean;
|
|
52
|
+
allowed_for_edit?: boolean;
|
|
53
|
+
replace?: boolean;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
schema: string;
|
|
56
|
+
action: string;
|
|
57
|
+
manifest_path: string;
|
|
58
|
+
asset: UeyeAssetEntry;
|
|
59
|
+
warnings: string[];
|
|
60
|
+
next_action: string;
|
|
61
|
+
truth_status: string;
|
|
62
|
+
}>;
|
|
63
|
+
export declare function verifyUeyeAssetManifest(manifestFile: string): Promise<{
|
|
64
|
+
schema: string;
|
|
65
|
+
manifest_path: string;
|
|
66
|
+
asset_count: number;
|
|
67
|
+
protected_count: number;
|
|
68
|
+
editable_count: number;
|
|
69
|
+
errors: string[];
|
|
70
|
+
warnings: string[];
|
|
71
|
+
ready: boolean;
|
|
72
|
+
next_action: string;
|
|
73
|
+
truth_status: string;
|
|
74
|
+
}>;
|
|
75
|
+
export declare function archiveUeyeRevision(input: {
|
|
76
|
+
file: string;
|
|
77
|
+
root: string;
|
|
78
|
+
manifest_path?: string;
|
|
79
|
+
round: number;
|
|
80
|
+
artifact_id?: string;
|
|
81
|
+
}): Promise<{
|
|
82
|
+
schema: string;
|
|
83
|
+
action: string;
|
|
84
|
+
manifest_path: string;
|
|
85
|
+
revision: UeyeRevisionEntry;
|
|
86
|
+
next_action: string;
|
|
87
|
+
truth_status: string;
|
|
88
|
+
}>;
|
|
89
|
+
export declare function verifyUeyeRevisionHistory(manifestFile: string): Promise<{
|
|
90
|
+
schema: string;
|
|
91
|
+
manifest_path: string;
|
|
92
|
+
revision_count: number;
|
|
93
|
+
rounds: number[];
|
|
94
|
+
errors: string[];
|
|
95
|
+
ready: boolean;
|
|
96
|
+
next_action: string;
|
|
97
|
+
truth_status: string;
|
|
98
|
+
}>;
|