ftown 0.20.9 → 0.24.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/attention-events.d.ts +1 -1
- package/dist/attention-store.d.ts +3 -0
- package/dist/attention-store.js +25 -1
- package/dist/attention-store.js.map +1 -1
- package/dist/centrifugo-client.d.ts +28 -11
- package/dist/centrifugo-client.js +84 -70
- package/dist/centrifugo-client.js.map +1 -1
- package/dist/cli-client.d.ts +11 -1
- package/dist/cli-client.js +23 -3
- package/dist/cli-client.js.map +1 -1
- package/dist/command-rpc.d.ts +2 -0
- package/dist/command-rpc.js +59 -17
- package/dist/command-rpc.js.map +1 -1
- package/dist/identity-reset.d.ts +4 -1
- package/dist/identity-reset.js +54 -6
- package/dist/identity-reset.js.map +1 -1
- package/dist/index.js +194 -288
- package/dist/index.js.map +1 -1
- package/dist/ledger-pairing-client.d.ts +28 -0
- package/dist/ledger-pairing-client.js +154 -0
- package/dist/ledger-pairing-client.js.map +1 -0
- package/dist/ledger-relay.d.ts +159 -0
- package/dist/ledger-relay.js +595 -0
- package/dist/ledger-relay.js.map +1 -0
- package/dist/ledger-reoffer.d.ts +56 -0
- package/dist/ledger-reoffer.js +210 -0
- package/dist/ledger-reoffer.js.map +1 -0
- package/dist/ledger-startup.d.ts +176 -0
- package/dist/ledger-startup.js +233 -0
- package/dist/ledger-startup.js.map +1 -0
- package/dist/local-api-server.d.ts +3 -0
- package/dist/local-api-server.js +68 -6
- package/dist/local-api-server.js.map +1 -1
- package/dist/mail-delivery.d.ts +26 -3
- package/dist/mail-delivery.js +65 -7
- package/dist/mail-delivery.js.map +1 -1
- package/dist/preview-protocol.d.ts +19 -3
- package/dist/preview-protocol.js +14 -0
- package/dist/preview-protocol.js.map +1 -1
- package/dist/relay-token.d.ts +45 -0
- package/dist/relay-token.js +138 -0
- package/dist/relay-token.js.map +1 -0
- package/dist/revocation-gating.d.ts +0 -13
- package/dist/revocation-gating.js +0 -16
- package/dist/revocation-gating.js.map +1 -1
- package/dist/security/bridge/identity.d.ts +2 -47
- package/dist/security/bridge/identity.js +3 -3
- package/dist/security/bridge/identity.js.map +1 -1
- package/dist/security/bridge/ledger-identity.d.ts +48 -0
- package/dist/security/bridge/ledger-identity.js +342 -0
- package/dist/security/bridge/ledger-identity.js.map +1 -0
- package/dist/security/bridge/ledger-rpc.d.ts +34 -0
- package/dist/security/bridge/ledger-rpc.js +58 -0
- package/dist/security/bridge/ledger-rpc.js.map +1 -0
- package/dist/security/bridge/ledger-store.d.ts +153 -0
- package/dist/security/bridge/ledger-store.js +825 -0
- package/dist/security/bridge/ledger-store.js.map +1 -0
- package/dist/security/bridge/metadata.d.ts +2 -2
- package/dist/security/bridge/permissions.js +4 -3
- package/dist/security/bridge/permissions.js.map +1 -1
- package/dist/security/bridge/policy.d.ts +43 -23
- package/dist/security/bridge/policy.js +214 -146
- package/dist/security/bridge/policy.js.map +1 -1
- package/dist/security/bridge/security.d.ts +212 -33
- package/dist/security/bridge/security.js +437 -165
- package/dist/security/bridge/security.js.map +1 -1
- package/dist/security/crypto.js +1 -1
- package/dist/security/crypto.js.map +1 -1
- package/dist/security/ledger/announce.d.ts +32 -0
- package/dist/security/ledger/announce.js +101 -0
- package/dist/security/ledger/announce.js.map +1 -0
- package/dist/security/ledger/channels.d.ts +5 -0
- package/dist/security/ledger/channels.js +21 -0
- package/dist/security/ledger/channels.js.map +1 -0
- package/dist/security/ledger/ledger.d.ts +154 -0
- package/dist/security/ledger/ledger.js +878 -0
- package/dist/security/ledger/ledger.js.map +1 -0
- package/dist/security/ledger/pairing.d.ts +81 -0
- package/dist/security/ledger/pairing.js +414 -0
- package/dist/security/ledger/pairing.js.map +1 -0
- package/dist/security/ledger/proof.d.ts +36 -0
- package/dist/security/ledger/proof.js +193 -0
- package/dist/security/ledger/proof.js.map +1 -0
- package/dist/security/ledger/protocol.d.ts +113 -0
- package/dist/security/ledger/protocol.js +16 -0
- package/dist/security/ledger/protocol.js.map +1 -0
- package/dist/security/ledger/testing.d.ts +27 -0
- package/dist/security/ledger/testing.js +70 -0
- package/dist/security/ledger/testing.js.map +1 -0
- package/dist/security/ledger/webauthn.d.ts +12 -0
- package/dist/security/ledger/webauthn.js +147 -0
- package/dist/security/ledger/webauthn.js.map +1 -0
- package/dist/security/protocol.d.ts +5 -10
- package/dist/security-cli.d.ts +5 -0
- package/dist/security-cli.js +28 -16
- package/dist/security-cli.js.map +1 -1
- package/dist/session-controller.d.ts +9 -3
- package/dist/session-controller.js +120 -20
- package/dist/session-controller.js.map +1 -1
- package/dist/session-inbox-protocol.d.ts +2 -0
- package/dist/session-preview.d.ts +20 -5
- package/dist/session-preview.js +185 -37
- package/dist/session-preview.js.map +1 -1
- package/dist/session-store.js +19 -1
- package/dist/session-store.js.map +1 -1
- package/dist/sessions-commands.js +41 -7
- package/dist/sessions-commands.js.map +1 -1
- package/dist/token-provider.d.ts +39 -0
- package/dist/token-provider.js +101 -0
- package/dist/token-provider.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/opencode-plugin/ftown.js +15 -2
- package/package.json +2 -2
- package/skills/ftown/SKILL.md +18 -7
- package/skills/ftown/references/sessions.md +38 -12
- package/dist/bridge-auth.d.ts +0 -31
- package/dist/bridge-auth.js +0 -70
- package/dist/bridge-auth.js.map +0 -1
- package/dist/pairing-client.d.ts +0 -62
- package/dist/pairing-client.js +0 -469
- package/dist/pairing-client.js.map +0 -1
- package/dist/rotating-token-refresher.d.ts +0 -42
- package/dist/rotating-token-refresher.js +0 -91
- package/dist/rotating-token-refresher.js.map +0 -1
- package/dist/security/account-crypto.d.ts +0 -33
- package/dist/security/account-crypto.js +0 -649
- package/dist/security/account-crypto.js.map +0 -1
- package/dist/security/account-protocol.d.ts +0 -228
- package/dist/security/account-protocol.js +0 -2
- package/dist/security/account-protocol.js.map +0 -1
- package/dist/security/bridge/account-client.d.ts +0 -7
- package/dist/security/bridge/account-client.js +0 -101
- package/dist/security/bridge/account-client.js.map +0 -1
- package/dist/security/bridge/account-state.d.ts +0 -105
- package/dist/security/bridge/account-state.js +0 -79
- package/dist/security/bridge/account-state.js.map +0 -1
- package/dist/security/bridge/pending-approval.d.ts +0 -21
- package/dist/security/bridge/pending-approval.js +0 -80
- package/dist/security/bridge/pending-approval.js.map +0 -1
- package/dist/security/bridge/pending-enrollment.d.ts +0 -33
- package/dist/security/bridge/pending-enrollment.js +0 -177
- package/dist/security/bridge/pending-enrollment.js.map +0 -1
- package/dist/security/bridge/revocation.d.ts +0 -14
- package/dist/security/bridge/revocation.js +0 -40
- package/dist/security/bridge/revocation.js.map +0 -1
- package/dist/security/pending-approval-crypto.d.ts +0 -29
- package/dist/security/pending-approval-crypto.js +0 -716
- package/dist/security/pending-approval-crypto.js.map +0 -1
- package/dist/security/pending-approval-protocol.d.ts +0 -329
- package/dist/security/pending-approval-protocol.js +0 -2
- package/dist/security/pending-approval-protocol.js.map +0 -1
- package/dist/security/security-nudge.d.ts +0 -31
- package/dist/security/security-nudge.js +0 -98
- package/dist/security/security-nudge.js.map +0 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { LedgerRelation } from '../ledger/ledger.js';
|
|
2
|
+
import type { BridgePairLink, PairApproval } from '../ledger/pairing.js';
|
|
3
|
+
import type { Ledger, LedgerCheckpoint, LedgerTransition, Signed } from '../ledger/protocol.js';
|
|
4
|
+
export type LedgerSource = 'server' | 'relay';
|
|
5
|
+
export type OwnBridgeStatus = 'active' | 'revoked' | 'absent';
|
|
6
|
+
export type ReconcileResult = 'ok' | 'unpaired' | 'needs_ledger';
|
|
7
|
+
export interface StickyRevocations {
|
|
8
|
+
deviceIds: string[];
|
|
9
|
+
bridgeIds: string[];
|
|
10
|
+
}
|
|
11
|
+
/** A valid history of this account from `source` that diverges from the stored chain and was refused. Times are wall-clock ms. */
|
|
12
|
+
export interface LedgerDivergence {
|
|
13
|
+
source: LedgerSource;
|
|
14
|
+
/** The refused chain's last head and revision (the first new head that source showed; an older refused head coming back changes nothing). */
|
|
15
|
+
otherHead: string;
|
|
16
|
+
otherRevision: number;
|
|
17
|
+
/** The revision of the last record both histories share; null when unknown (an entry written by an earlier 0.22 build). */
|
|
18
|
+
forkRevision: number | null;
|
|
19
|
+
/** A refused history from this source removes THIS bridge (status only: never a sticky entry, never an identity reset). */
|
|
20
|
+
removedOnOtherHistory: boolean;
|
|
21
|
+
/** When this source was first seen diverging (kept while it keeps diverging, also when its head moves). */
|
|
22
|
+
firstSeen: number;
|
|
23
|
+
/** When it was last seen; persisted at most every DIVERGENCE_LAST_SEEN_RESOLUTION_MS. */
|
|
24
|
+
lastSeen: number;
|
|
25
|
+
}
|
|
26
|
+
/** The last REFUSED_HEADS_PER_SOURCE refused heads per source, oldest first: a REFUSED line is logged once per head (persisted, so also
|
|
27
|
+
* across restarts and after the divergence entry was cleared). */
|
|
28
|
+
export interface RefusedHeads {
|
|
29
|
+
server: string[];
|
|
30
|
+
relay: string[];
|
|
31
|
+
}
|
|
32
|
+
/** This bridge's own keys, exactly as its add_bridge lists them (and as BridgeSecurityService's 'active' check compares them). */
|
|
33
|
+
export interface OwnBridgeKeys {
|
|
34
|
+
bridgeId: string;
|
|
35
|
+
endpointId: string;
|
|
36
|
+
endpointPublicKey: string;
|
|
37
|
+
authPublicKey: string;
|
|
38
|
+
}
|
|
39
|
+
export interface BridgeLedgerState {
|
|
40
|
+
ledger: Ledger;
|
|
41
|
+
/** The stored chain's own checkpoint (raw). Never use it for a trust decision. */
|
|
42
|
+
checkpoint: LedgerCheckpoint;
|
|
43
|
+
/** applyRevocations(checkpoint, sticky): the checkpoint for every trust decision. */
|
|
44
|
+
trusted: LedgerCheckpoint;
|
|
45
|
+
/** The revocations of every chain this replica adopted, plus those of records an owner-chosen history discarded, plus the removals
|
|
46
|
+
* chooseLedger saw on refused histories (`seen`, C1c) except this bridge's own id. Trust only, never evidence of this bridge's removal. */
|
|
47
|
+
sticky: StickyRevocations;
|
|
48
|
+
lastServerReadAt: number | null;
|
|
49
|
+
/** At most one entry per source, ordered server first. */
|
|
50
|
+
divergences: LedgerDivergence[];
|
|
51
|
+
refused: RefusedHeads;
|
|
52
|
+
}
|
|
53
|
+
/** The last record of a chain: its revision (0 = genesis) and head (the genesis head is the accountId). */
|
|
54
|
+
export interface LedgerTip {
|
|
55
|
+
revision: number;
|
|
56
|
+
head: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LedgerOfferResult {
|
|
59
|
+
decision: 'adopt' | 'keep' | 'reject';
|
|
60
|
+
/** How the candidate relates to the chain stored before the decision; null when it has none (empty store, malformed, another account). */
|
|
61
|
+
relation: LedgerRelation | null;
|
|
62
|
+
/** The candidate's tip; null when it does not parse. */
|
|
63
|
+
candidate: LedgerTip | null;
|
|
64
|
+
/** The stored state after the decision; null while the store is empty. */
|
|
65
|
+
state: BridgeLedgerState | null;
|
|
66
|
+
/** Local records an owner-chosen history (adopt + diverged) discarded; empty otherwise. */
|
|
67
|
+
discarded: Signed<LedgerTransition>[];
|
|
68
|
+
/** A diverged candidate that a resolve_fork already in OUR chain discards (the other side is behind the owner's decision): answered
|
|
69
|
+
* keep with relation 'behind' (so a server holding it gets our chain re-offered), never recorded as a divergence, never logged. */
|
|
70
|
+
covered: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface BridgeLedgerStoreOptions {
|
|
73
|
+
/** The account the bridge identity is bound to: ledgers of any other account are rejected even while the store is empty, and a
|
|
74
|
+
* stored ledger of another account throws LedgerStoreError('ledger_store_wrong_account'). */
|
|
75
|
+
accountId?: string | null;
|
|
76
|
+
now?: () => number;
|
|
77
|
+
/** The `[ledger]` lines (refused history, owner-chosen adoption, ignored chain). Defaults to console.warn. */
|
|
78
|
+
log?: (line: string) => void;
|
|
79
|
+
/** This bridge's own bridgeId. A refused history's removal of it is recorded as status only, never added to the sticky set. Without it,
|
|
80
|
+
* no bridge removal of a refused history is added to the sticky set at all (device removals still are). */
|
|
81
|
+
bridgeId?: string | null;
|
|
82
|
+
}
|
|
83
|
+
/** Divergence lastSeen is rewritten at most this often while the same other head keeps arriving. */
|
|
84
|
+
export declare const DIVERGENCE_LAST_SEEN_RESOLUTION_MS: number;
|
|
85
|
+
/** "ignored an invalid chain" is logged at most once per this interval per source. */
|
|
86
|
+
export declare const INVALID_CHAIN_LOG_SPACING_MS = 60000;
|
|
87
|
+
/** A REFUSED line for a head not refused before is logged at most once per this interval per source. */
|
|
88
|
+
export declare const REFUSED_LOG_SPACING_MS = 60000;
|
|
89
|
+
/** Refused heads remembered per source (persisted), and verdicts on refused chains cached per process. */
|
|
90
|
+
export declare const REFUSED_HEADS_PER_SOURCE = 16;
|
|
91
|
+
export declare const REFUSED_VERDICT_CACHE_SIZE = 16;
|
|
92
|
+
/** The first 8 characters of a head, as the log lines and the status show it. */
|
|
93
|
+
export declare const shortHead: (head: string) => string;
|
|
94
|
+
export type LedgerStoreErrorCode = 'ledger_store_corrupt' | 'ledger_store_wrong_account' | 'ledger_store_pairing_rejected' | 'ledger_store_pairing_revoked' | 'ledger_store_bound_rejected';
|
|
95
|
+
/** Not retryable; file contents and crypto errors never enter it. Read/write failures throw BridgeSecurityError('storage_unavailable'). */
|
|
96
|
+
export declare class LedgerStoreError extends Error {
|
|
97
|
+
readonly code: LedgerStoreErrorCode;
|
|
98
|
+
readonly retryable = false;
|
|
99
|
+
constructor(code: LedgerStoreErrorCode);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Proof in the RAW chain `ledger` that THIS bridge was removed: an add_bridge of exactly these keys (bridgeId, endpoint id, endpoint public
|
|
103
|
+
* key and auth key), followed by a revoke_bridge of its bridgeId. A revoke_bridge of an id the chain never added with these keys is only a
|
|
104
|
+
* tombstone (C1b: revoking a non-member is valid) and proves nothing about this bridge. Sticky entries and refused histories never count:
|
|
105
|
+
* this is the only evidence that resets the identity, on a running bridge and at startup alike.
|
|
106
|
+
*/
|
|
107
|
+
export declare function ledgerRemovesBridge(ledger: Ledger, own: OwnBridgeKeys): boolean;
|
|
108
|
+
export declare class BridgeLedgerStore {
|
|
109
|
+
private readonly replica;
|
|
110
|
+
constructor(dataDir: string, options?: BridgeLedgerStoreOptions);
|
|
111
|
+
/** The stored state, or null while no ledger is stored. Throws LedgerStoreError for a corrupted or wrong-account file. */
|
|
112
|
+
read(): Promise<BridgeLedgerState | null>;
|
|
113
|
+
/** applyRevocations(checkpoint, sticky) of the stored chain, or null while no ledger is stored. */
|
|
114
|
+
trusted(): Promise<LedgerCheckpoint | null>;
|
|
115
|
+
/** The startup decision (ledger-startup ownStatusAction): 'active' iff trusted() lists this bridge with exactly its keys; 'revoked' iff the
|
|
116
|
+
* stored RAW chain proves its removal (ledgerRemovesBridge: it added these keys, then revoked the id); else 'absent' (a tombstone, a
|
|
117
|
+
* sticky-only id or a removal seen on a refused history is no removal). The same rule as BridgeSecurityService's running check. */
|
|
118
|
+
ownBridgeStatus(own: OwnBridgeKeys): Promise<OwnBridgeStatus>;
|
|
119
|
+
/**
|
|
120
|
+
* Offers an untrusted candidate chain from the server or the relay (see decide for the rule). Never binds an empty store, and never
|
|
121
|
+
* throws for a bad candidate: it is rejected. Throws LedgerStoreError for a corrupted or wrong-account local file, and
|
|
122
|
+
* BridgeSecurityError('storage_unavailable') when the file cannot be read or written.
|
|
123
|
+
*/
|
|
124
|
+
offer(candidate: unknown, source: LedgerSource): Promise<LedgerOfferResult>;
|
|
125
|
+
/**
|
|
126
|
+
* The pairing path, after openPairApproval. Runs confirmPairedLedger(link, approval, ledger, now, sticky) with this replica's sticky
|
|
127
|
+
* set, then binds the empty store (or applies the append-only rule to a bound store of the same account); the request's bridge must be in
|
|
128
|
+
* the resulting trusted roster. Returns trusted(). Throws LedgerStoreError('ledger_store_pairing_revoked') when the chain (or this
|
|
129
|
+
* replica's sticky set) revokes the request's bridge id, LedgerStoreError('ledger_store_pairing_rejected') on any other pairing failure;
|
|
130
|
+
* writes nothing in either case.
|
|
131
|
+
*/
|
|
132
|
+
adoptPaired(link: BridgePairLink, approval: PairApproval, ledger: unknown, now?: number): Promise<LedgerCheckpoint>;
|
|
133
|
+
/**
|
|
134
|
+
* Recovery when the identity is bound but the store is empty (reconcileIdentityAndStore returned 'needs_ledger'): accepts a server
|
|
135
|
+
* ledger only if its account is the identity's bound account and its trusted roster lists this identity's bridge keys (endpoint id and
|
|
136
|
+
* authPublicKey). Returns trusted(). Throws LedgerStoreError('ledger_store_bound_rejected') and writes nothing otherwise.
|
|
137
|
+
*/
|
|
138
|
+
adoptBound(ledger: unknown, now?: number): Promise<LedgerCheckpoint>;
|
|
139
|
+
/** Records the time of the last successful server ledger read. No-op while no ledger is stored. */
|
|
140
|
+
markServerRead(now: number): Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Startup recovery between the identity file and the ledger store, under the store's queue:
|
|
144
|
+
* - identity bound, store holds its account's ledger -> 'ok'; store holds another account's -> throws ledger_store_wrong_account;
|
|
145
|
+
* - identity bound, store empty -> 'needs_ledger' (fetch the server ledger, then adoptBound); a bound identity is never unbound;
|
|
146
|
+
* - identity unbound (or absent), store empty -> 'unpaired';
|
|
147
|
+
* - identity unbound, store's trusted roster lists this identity's bridge keys -> binds the identity to that account -> 'ok';
|
|
148
|
+
* - otherwise (absent identity, or keys not listed) the stale ledger.json is deleted -> 'unpaired'.
|
|
149
|
+
* Corrupted files throw (LedgerStoreError / BridgeSecurityError('key_unavailable')) and are never reset.
|
|
150
|
+
*/
|
|
151
|
+
export declare function reconcileIdentityAndStore(dataDir: string, options?: {
|
|
152
|
+
now?: () => number;
|
|
153
|
+
}): Promise<ReconcileResult>;
|