sememe 0.0.0-stage → 0.4.22

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2777 -2
  3. package/bin/sememe.mjs +556 -0
  4. package/index.mjs +48 -0
  5. package/interface/ata-ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL.json +62 -0
  6. package/interface/native-11111111111111111111111111111111.json +226 -0
  7. package/interface/native-ComputeBudget111111111111111111111111111111.json +72 -0
  8. package/interface/raydium-675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8.json +352 -0
  9. package/interface/token-TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA.json +334 -0
  10. package/interface/token-TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb.json +535 -0
  11. package/interface/token-metadata.json +132 -0
  12. package/package.json +71 -4
  13. package/src/account-list.mjs +308 -0
  14. package/src/account-union.mjs +523 -0
  15. package/src/account.mjs +199 -0
  16. package/src/acquire.mjs +145 -0
  17. package/src/adopt.mjs +206 -0
  18. package/src/ata-interface.mjs +276 -0
  19. package/src/ata.mjs +223 -0
  20. package/src/base58.mjs +96 -0
  21. package/src/canonical.mjs +24 -0
  22. package/src/cli-surface.mjs +300 -0
  23. package/src/codec.mjs +1118 -0
  24. package/src/conformance.mjs +431 -0
  25. package/src/corpus/harvest-compute-budget-2026-10-31.json +19122 -0
  26. package/src/corpus/harvest-system-2026-10-31.json +26090 -0
  27. package/src/decode.mjs +286 -0
  28. package/src/dialect.mjs +180 -0
  29. package/src/discriminators.mjs +192 -0
  30. package/src/drift.mjs +172 -0
  31. package/src/gap.mjs +205 -0
  32. package/src/lighthouse.mjs +168 -0
  33. package/src/lock.mjs +440 -0
  34. package/src/native-audit.mjs +56 -0
  35. package/src/native-corpus.mjs +57 -0
  36. package/src/native-interface.mjs +252 -0
  37. package/src/native.mjs +324 -0
  38. package/src/peer.mjs +95 -0
  39. package/src/program-id.mjs +74 -0
  40. package/src/pull.mjs +117 -0
  41. package/src/rawle.mjs +454 -0
  42. package/src/raydium-interface.mjs +747 -0
  43. package/src/raydium.mjs +391 -0
  44. package/src/receipt-digest.mjs +84 -0
  45. package/src/receipt-name.mjs +128 -0
  46. package/src/receipt-order.mjs +56 -0
  47. package/src/shank.mjs +73 -0
  48. package/src/short-forms.mjs +209 -0
  49. package/src/store-read.mjs +253 -0
  50. package/src/store-write.mjs +46 -0
  51. package/src/token-interface.mjs +394 -0
  52. package/src/token-metadata-interface.mjs +371 -0
  53. package/src/token-metadata.mjs +317 -0
  54. package/src/token.mjs +443 -0
  55. package/src/union.mjs +428 -0
  56. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/LICENSE.txt +201 -0
  57. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/compute-budget-interface/src/lib.rs +93 -0
  58. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/system-interface/src/instruction.rs +1899 -0
  59. package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/LICENSE +21 -0
  60. package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/lighthouse.json +2769 -0
  61. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/LICENSE +201 -0
  62. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/instruction.rs +1189 -0
  63. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/state.rs +1348 -0
  64. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/LICENSE +201 -0
  65. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/instruction.rs +169 -0
  66. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/lib.rs +12 -0
  67. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/program/src/processor.rs +308 -0
  68. package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/LICENSE.txt +176 -0
  69. package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/interface/src/instruction.rs +1963 -0
  70. package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/LICENSE.txt +176 -0
  71. package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/interface/src/instruction.rs +2868 -0
  72. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/LICENSE +201 -0
  73. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/error.rs +58 -0
  74. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/instruction.rs +596 -0
  75. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/lib.rs +21 -0
  76. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/state.rs +229 -0
@@ -0,0 +1,300 @@
1
+ // The CLI's DECLARED surface: which flags each command accepts and how many
2
+ // positional arguments it consumes.
3
+ //
4
+ // Why this file exists (measured 2026-11-06, on the working tree at 641b895):
5
+ //
6
+ // The CLI parsed flags by SEARCHING the argument list for a name and taking
7
+ // whatever came next. A flag the command does not know was therefore not an
8
+ // error — it was silently discarded, and so was every extra positional
9
+ // argument. The consequences were measured on the real CLI:
10
+ //
11
+ // sememe lock --store <valid> --o out.lock
12
+ // -> exit 0, a lock written to ./sememe.lock, NOT to out.lock.
13
+ // The caller asked for a file at one path and got a file at another,
14
+ // with a success exit code.
15
+ // sememe decode <prog> <payload> --stro ./store
16
+ // -> exit 1, "no sememe store at /home/<user>/.sememe": the typo'd
17
+ // --store was dropped and the DEFAULT store was used instead.
18
+ // sememe verify --store <valid> --lock <valid> --mod warn
19
+ // -> --mod dropped; verify ran in its default error mode.
20
+ // sememe native-provenance --store <dir>
21
+ // -> "--store is not a native program sememe pins": the flag's VALUE was
22
+ // read as the program id.
23
+ // sememe decode --store <valid> <prog> <payload>
24
+ // -> "no sememe store at /home/<user>/.sememe": with a flag in the
25
+ // program slot, the STORE PATH was read as the payload and the
26
+ // program id as the store.
27
+ // sememe pull <prog> --stor <dir>
28
+ // -> the typo was dropped and the pull RAN against the default store:
29
+ // a write the caller never asked for.
30
+ // sememe decode <prog> <payload> --store A --store B
31
+ // -> A was used, B was silently ignored.
32
+ //
33
+ // A parser error here is a silent change of WHAT gets read, signed, pinned or
34
+ // written. The rule this file implements is the one the repository already
35
+ // applies to stores, receipts and locks: an unrecognized input is REFUSED BY
36
+ // NAME, never tolerated.
37
+ //
38
+ // Two deliberate properties:
39
+ //
40
+ // - The check runs BEFORE any command does work. No store is read, no file
41
+ // is written, no RPC is contacted, no key is touched. A refusal must not
42
+ // have a side effect.
43
+ // - The refusal NAMES THE REPAIR: the offending flag, the closest supported
44
+ // flag (measured by edit distance), and the full supported list. "unknown
45
+ // flag" alone is a verdict, not a repair.
46
+ //
47
+ // The table is DATA, not code paths, so it can be read and pinned. The CLI
48
+ // dispatch reads it; nothing else may add a flag to a command without adding
49
+ // it here, which is exactly the drift this file exists to make visible.
50
+
51
+ /** A refusal about the SHAPE of the invocation, not about what it produced. */
52
+ export class UsageError extends Error {
53
+ constructor(message) {
54
+ super(message);
55
+ this.name = 'UsageError';
56
+ this.code = 'usage';
57
+ }
58
+ }
59
+
60
+ /**
61
+ * The per-command surface.
62
+ *
63
+ * flags the flags the command accepts; 'value' takes the next token,
64
+ * 'boolean' stands alone
65
+ * positionals how many positional arguments the command consumes, either a
66
+ * fixed count or [min, max] for an optional one
67
+ * positionalNames the names used in the refusal message
68
+ * extraMessage a command-specific refusal for a surplus positional argument
69
+ * (lock/verify have their own wording, and it has been the
70
+ * product's wording since the lock shipped)
71
+ */
72
+ export const COMMAND_SPECS = {
73
+ 'absent-help': { flags: {}, positionals: 0 },
74
+ pull: {
75
+ flags: { '--store': 'value', '--rpc': 'value' },
76
+ positionals: 1,
77
+ positionalNames: ['program id'],
78
+ },
79
+ gap: {
80
+ flags: { '--rpc': 'value' },
81
+ positionals: 1,
82
+ positionalNames: ['program id'],
83
+ },
84
+ lock: {
85
+ flags: { '--store': 'value', '--out': 'value' },
86
+ positionals: 0,
87
+ extraMessage: (extras) => `lock takes no program id — it snapshots the whole store; got "${extras[0]}"`,
88
+ },
89
+ verify: {
90
+ flags: { '--store': 'value', '--lock': 'value', '--mode': 'value' },
91
+ positionals: 0,
92
+ extraMessage: (extras) => `verify takes no program id — it checks the whole lock; got "${extras[0]}"`,
93
+ },
94
+ adopt: {
95
+ flags: { '--store': 'value', '--source': 'value', '--origin': 'value' },
96
+ positionals: 2,
97
+ positionalNames: ['program id', 'interface file'],
98
+ },
99
+ 'adopt-lighthouse': {
100
+ flags: { '--store': 'value' },
101
+ positionals: 0,
102
+ },
103
+ decode: {
104
+ flags: { '--store': 'value', '--trailing': 'value', '--absent': 'value', '--union': 'boolean' },
105
+ positionals: 2,
106
+ positionalNames: ['program id', 'payload'],
107
+ },
108
+ conform: {
109
+ flags: { '--store': 'value', '--only': 'value' },
110
+ positionals: 1,
111
+ positionalNames: ['transaction file'],
112
+ },
113
+ 'decode-native': {
114
+ flags: { '--trailing': 'value' },
115
+ positionals: 2,
116
+ positionalNames: ['program id', 'payload'],
117
+ },
118
+ 'native-provenance': {
119
+ flags: {},
120
+ positionals: [0, 1],
121
+ positionalNames: ['program id'],
122
+ },
123
+ 'decode-token': {
124
+ flags: { '--trailing': 'value' },
125
+ positionals: 2,
126
+ positionalNames: ['program id', 'payload'],
127
+ },
128
+ 'token-provenance': {
129
+ flags: {},
130
+ positionals: [0, 1],
131
+ positionalNames: ['program id'],
132
+ },
133
+ 'raydium-provenance': {
134
+ flags: {},
135
+ positionals: [0, 1],
136
+ positionalNames: ['program id'],
137
+ },
138
+ 'decode-raydium': {
139
+ flags: { '--trailing': 'value' },
140
+ positionals: 2,
141
+ positionalNames: ['program id', 'payload'],
142
+ },
143
+ 'decode-ata': {
144
+ flags: { '--trailing': 'value', '--empty': 'boolean' },
145
+ positionals: [1, 2],
146
+ positionalNames: ['program id', 'payload'],
147
+ },
148
+ 'ata-provenance': {
149
+ flags: {},
150
+ positionals: [0, 1],
151
+ positionalNames: ['program id'],
152
+ },
153
+ account: {
154
+ flags: { '--store': 'value', '--name': 'value', '--trailing': 'value', '--union': 'boolean' },
155
+ positionals: 2,
156
+ positionalNames: ['program id', 'account data'],
157
+ },
158
+ };
159
+
160
+ /** The command names this CLI knows, in the order the usage text lists them. */
161
+ export const COMMAND_NAMES = Object.keys(COMMAND_SPECS);
162
+
163
+ /** Levenshtein distance — enough to suggest a flag, not a spellchecker. */
164
+ export function editDistance(a, b) {
165
+ const s = String(a);
166
+ const t = String(b);
167
+ if (s === t) return 0;
168
+ if (!s.length) return t.length;
169
+ if (!t.length) return s.length;
170
+ let prev = Array.from({ length: t.length + 1 }, (_, i) => i);
171
+ for (let i = 1; i <= s.length; i++) {
172
+ const cur = [i];
173
+ for (let j = 1; j <= t.length; j++) {
174
+ const cost = s[i - 1] === t[j - 1] ? 0 : 1;
175
+ cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
176
+ }
177
+ prev = cur;
178
+ }
179
+ return prev[t.length];
180
+ }
181
+
182
+ /**
183
+ * The closest supported flag, when one is close enough to be a plausible
184
+ * typo. "Close enough" is measured, not guessed: within two edits, or within
185
+ * a quarter of the flag's own length.
186
+ *
187
+ * The quarter rule matters: the flag `--absent-help` is three edits away from
188
+ * the flag `--absent`, but it is not a typo of it — it is a COMMAND name with a
189
+ * prefix — so a distance of three must NOT produce a suggestion. Two edits is
190
+ * the line.
191
+ */
192
+ export function closestFlag(flag, supported) {
193
+ const target = String(flag);
194
+ let best = null;
195
+ let bestDistance = Infinity;
196
+ for (const candidate of supported) {
197
+ const distance = editDistance(target, candidate);
198
+ if (distance < bestDistance) {
199
+ bestDistance = distance;
200
+ best = candidate;
201
+ }
202
+ }
203
+ if (best === null) return null;
204
+ const limit = Math.max(2, Math.floor(target.length / 4));
205
+ return bestDistance <= limit ? best : null;
206
+ }
207
+
208
+ /**
209
+ * The refusal for a flag the command does not accept.
210
+ *
211
+ * The supported list appears exactly ONCE. Measured on the published
212
+ * v0.4.7 install 2026-11-07 (a defect found by running the README examples
213
+ * verbatim against the packed tarball, not by a unit test): the first
214
+ * version printed the list in the no-suggestion clause AND again at the end,
215
+ * so `decode … --rpc` printed the same four flags twice in one line.
216
+ */
217
+ export function unknownFlagMessage(command, flag, supported) {
218
+ const suggestion = closestFlag(flag, supported);
219
+ if (suggestion) {
220
+ return `sememe ${command}: unknown flag "${flag}" — did you mean "${suggestion}"? supported flags: ${supported.join(', ')}`;
221
+ }
222
+ if (!supported.length) {
223
+ return `sememe ${command}: unknown flag "${flag}" — this command accepts no flags`;
224
+ }
225
+ return `sememe ${command}: unknown flag "${flag}" — supported flags: ${supported.join(', ')}`;
226
+ }
227
+
228
+ /** The refusal for a surplus positional argument. */
229
+ export function extraPositionalMessage(command, extras, spec) {
230
+ if (typeof spec?.extraMessage === 'function') return spec.extraMessage(extras);
231
+ const expected = Array.isArray(spec?.positionals) ? spec.positionals[1] : spec?.positionals;
232
+ const names = (spec?.positionalNames ?? []).join(', ');
233
+ return `sememe ${command} takes ${expected} positional argument${expected === 1 ? '' : 's'}`
234
+ + `${names ? ` (${names})` : ''}; got ${expected + extras.length} — extra: ${extras.map((e) => JSON.stringify(e)).join(', ')}`;
235
+ }
236
+
237
+ /**
238
+ * Parse one command's arguments against its spec.
239
+ *
240
+ * Returns { flags, positionals }. Throws UsageError for anything the command
241
+ * does not declare. The order of the checks is the point:
242
+ *
243
+ * 1. every flag is checked FIRST, before any value is consumed — so a
244
+ * typo'd flag is refused as a typo, not silently reinterpreted as
245
+ * something else;
246
+ * 2. a flag that needs a value but has none is refused naming the flag;
247
+ * 3. a flag given twice is refused: the second value would otherwise be
248
+ * silently dropped, and the caller would believe the LAST one won
249
+ * (it does not — the FIRST one wins, which is the worse surprise);
250
+ * 4. only then is the positional count checked.
251
+ *
252
+ * A command this CLI does not know is NOT an error here: the caller prints
253
+ * the usage text for it, which is the product's existing behaviour.
254
+ */
255
+ export function parseCommandArgs(command, tokens) {
256
+ const spec = COMMAND_SPECS[command];
257
+ if (!spec) return { flags: {}, positionals: [] };
258
+ const supported = Object.keys(spec.flags);
259
+ const flags = {};
260
+ const positionals = [];
261
+ const list = Array.isArray(tokens) ? tokens : [];
262
+
263
+ for (let i = 0; i < list.length; i++) {
264
+ const token = list[i];
265
+ if (typeof token !== 'string' || !token.startsWith('--')) {
266
+ positionals.push(token);
267
+ continue;
268
+ }
269
+ const kind = spec.flags[token];
270
+ if (!kind) throw new UsageError(unknownFlagMessage(command, token, supported));
271
+ if (Object.prototype.hasOwnProperty.call(flags, token)) {
272
+ throw new UsageError(`sememe ${command}: flag "${token}" given more than once — pass it once`);
273
+ }
274
+ if (kind === 'boolean') {
275
+ flags[token] = true;
276
+ continue;
277
+ }
278
+ const value = list[i + 1];
279
+ if (value === undefined || (typeof value === 'string' && value.startsWith('--'))) {
280
+ throw new UsageError(`sememe ${command}: missing value for ${token}`);
281
+ }
282
+ flags[token] = value;
283
+ i++;
284
+ }
285
+
286
+ const [min, max] = Array.isArray(spec.positionals)
287
+ ? spec.positionals
288
+ : [spec.positionals, spec.positionals];
289
+ if (positionals.length > max) {
290
+ throw new UsageError(extraPositionalMessage(command, positionals.slice(max), spec));
291
+ }
292
+ if (positionals.length < min) {
293
+ // Too FEW positionals is the command's own business: every command
294
+ // already refuses with its own wording ("decode needs a program id"),
295
+ // and that wording is pinned by other tests. Only the surplus case is
296
+ // decided here.
297
+ return { flags, positionals };
298
+ }
299
+ return { flags, positionals };
300
+ }