tenjin-cli 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (133) hide show
  1. package/NOTICE.md +33 -0
  2. package/README.md +167 -16
  3. package/dist/{_esm-ZH2J4QEH.js → _esm-C5CRWCYU.js} +2 -2
  4. package/dist/_esm-FEASBWRP.js +881 -0
  5. package/dist/buy-EE6SEXP6.js +1598 -0
  6. package/dist/buy-EE6SEXP6.js.map +1 -0
  7. package/dist/candidate-ERMSYYQZ.js +127 -0
  8. package/dist/candidate-ERMSYYQZ.js.map +1 -0
  9. package/dist/{ccip-UCLT5VOW.js → ccip-NQXCEK2U.js} +6 -5
  10. package/dist/ccip-XR5NE5QK.js +19 -0
  11. package/dist/chunk-2I4QTOLB.js +11 -0
  12. package/dist/chunk-2I4QTOLB.js.map +1 -0
  13. package/dist/chunk-3OV7E5G5.js +18 -0
  14. package/dist/chunk-3OV7E5G5.js.map +1 -0
  15. package/dist/chunk-4ONXEEQL.js +152 -0
  16. package/dist/chunk-4ONXEEQL.js.map +1 -0
  17. package/dist/chunk-5CLSD5YN.js +209 -0
  18. package/dist/chunk-5CLSD5YN.js.map +1 -0
  19. package/dist/chunk-662MSGZB.js +286 -0
  20. package/dist/chunk-662MSGZB.js.map +1 -0
  21. package/dist/chunk-7KUW4MJD.js +59 -0
  22. package/dist/chunk-7KUW4MJD.js.map +1 -0
  23. package/dist/{doctor-3QBYN46N.js → chunk-AWPAWHNX.js} +88 -93
  24. package/dist/chunk-AWPAWHNX.js.map +1 -0
  25. package/dist/chunk-CYOF7ROH.js +70 -0
  26. package/dist/chunk-CYOF7ROH.js.map +1 -0
  27. package/dist/chunk-DXTQ3CSI.js +171 -0
  28. package/dist/chunk-DXTQ3CSI.js.map +1 -0
  29. package/dist/{chunk-EZROUI5U.js → chunk-ESPNTPQ2.js} +80 -8
  30. package/dist/chunk-ESPNTPQ2.js.map +1 -0
  31. package/dist/chunk-FJPLRISB.js +79 -0
  32. package/dist/chunk-FJPLRISB.js.map +1 -0
  33. package/dist/chunk-GO75V3NZ.js +160 -0
  34. package/dist/chunk-GO75V3NZ.js.map +1 -0
  35. package/dist/chunk-HIVZG55D.js +204 -0
  36. package/dist/chunk-HIVZG55D.js.map +1 -0
  37. package/dist/chunk-HSDCI7OV.js +7806 -0
  38. package/dist/chunk-HSDCI7OV.js.map +1 -0
  39. package/dist/chunk-JPHG2JW3.js +96 -0
  40. package/dist/chunk-JPHG2JW3.js.map +1 -0
  41. package/dist/{chunk-ZPZFPVDN.js → chunk-MUBUQVC3.js} +1 -1
  42. package/dist/chunk-MUBUQVC3.js.map +1 -0
  43. package/dist/{chunk-T4LKNY7T.js → chunk-NCE5NSN6.js} +166 -11
  44. package/dist/chunk-NCE5NSN6.js.map +1 -0
  45. package/dist/{chunk-YG2DO46P.js → chunk-OYMYCW7J.js} +18 -3
  46. package/dist/{chunk-YG2DO46P.js.map → chunk-OYMYCW7J.js.map} +1 -1
  47. package/dist/{chunk-Q53IYV2G.js → chunk-QVX5MWJZ.js} +20 -17
  48. package/dist/{chunk-Q53IYV2G.js.map → chunk-QVX5MWJZ.js.map} +1 -1
  49. package/dist/{chunk-CUWUHTIL.js → chunk-RBJPAZFI.js} +16 -202
  50. package/dist/chunk-RBJPAZFI.js.map +1 -0
  51. package/dist/chunk-RRN3YTK7.js +6199 -0
  52. package/dist/chunk-RRN3YTK7.js.map +1 -0
  53. package/dist/chunk-RY4XKNV3.js +140 -0
  54. package/dist/chunk-RY4XKNV3.js.map +1 -0
  55. package/dist/chunk-S3IGX57D.js +14682 -0
  56. package/dist/chunk-S3IGX57D.js.map +1 -0
  57. package/dist/chunk-TLCMMYLY.js +126 -0
  58. package/dist/chunk-TLCMMYLY.js.map +1 -0
  59. package/dist/{chunk-IPOWB3G3.js → chunk-UGX7YPX2.js} +3314 -306
  60. package/dist/chunk-UGX7YPX2.js.map +1 -0
  61. package/dist/chunk-UO22YNY4.js +69 -0
  62. package/dist/chunk-UO22YNY4.js.map +1 -0
  63. package/dist/{config-CEFTL5ZL.js → chunk-XHC6FCGZ.js} +115 -18
  64. package/dist/chunk-XHC6FCGZ.js.map +1 -0
  65. package/dist/chunk-XJIW7USF.js +217 -0
  66. package/dist/chunk-XJIW7USF.js.map +1 -0
  67. package/dist/{chunk-BRJHUQSY.js → chunk-YALGASEU.js} +1548 -1452
  68. package/dist/chunk-YALGASEU.js.map +1 -0
  69. package/dist/{chunk-DXPYFVKG.js → chunk-YN5SHIXQ.js} +6 -6
  70. package/dist/chunk-YN5SHIXQ.js.map +1 -0
  71. package/dist/chunk-Z52RA3NC.js +137 -0
  72. package/dist/chunk-Z52RA3NC.js.map +1 -0
  73. package/dist/{chunk-EXBMF5X7.js → chunk-Z6MFJV5Z.js} +151 -19
  74. package/dist/chunk-Z6MFJV5Z.js.map +1 -0
  75. package/dist/chunk-ZABPQJ3M.js +83 -0
  76. package/dist/chunk-ZABPQJ3M.js.map +1 -0
  77. package/dist/{chunk-LPRVHM7P.js → chunk-ZMHYXMO6.js} +1655 -114
  78. package/dist/chunk-ZMHYXMO6.js.map +1 -0
  79. package/dist/{chunk-3IMLRUZE.js → chunk-ZXTAQYNA.js} +6 -2
  80. package/dist/{cli-WA65NP4Y.js → cli-SBXI5AMS.js} +177 -177
  81. package/dist/cli-SBXI5AMS.js.map +1 -0
  82. package/dist/config-VELDKLHY.js +21 -0
  83. package/dist/doctor-T3KWNNP2.js +20 -0
  84. package/dist/doctor-T3KWNNP2.js.map +1 -0
  85. package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js +18 -0
  86. package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js.map +1 -0
  87. package/dist/index.js +1 -1
  88. package/dist/inspect-LMKOXE4Y.js +96 -0
  89. package/dist/inspect-LMKOXE4Y.js.map +1 -0
  90. package/dist/install-LEX3ENQ6.js +387 -0
  91. package/dist/install-LEX3ENQ6.js.map +1 -0
  92. package/dist/lookup-ZPN2Q67N.js +129 -0
  93. package/dist/lookup-ZPN2Q67N.js.map +1 -0
  94. package/dist/{mine.wasm-GQECMSGN.js → mine.wasm-6PIT3DK6.js} +2 -2
  95. package/dist/outcome-N7TAK6WR.js +66 -0
  96. package/dist/outcome-N7TAK6WR.js.map +1 -0
  97. package/dist/publish-BKBQQAW4.js +1478 -0
  98. package/dist/publish-BKBQQAW4.js.map +1 -0
  99. package/dist/{secp256k1-BEZS642W.js → secp256k1-N3ZHU7LB.js} +5 -4
  100. package/dist/secp256k1-N3ZHU7LB.js.map +1 -0
  101. package/dist/usdc-JIAJW4SV.js +22 -0
  102. package/dist/usdc-JIAJW4SV.js.map +1 -0
  103. package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js +14 -0
  104. package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js.map +1 -0
  105. package/dist/{wallet-XD576HF3.js → wallet-CWEMYVIH.js} +28 -22
  106. package/dist/{wallet-XD576HF3.js.map → wallet-CWEMYVIH.js.map} +1 -1
  107. package/dist/wallet-PA54CRBL.js +30 -0
  108. package/dist/wallet-PA54CRBL.js.map +1 -0
  109. package/package.json +19 -16
  110. package/skills/tenjin/SKILL.md +199 -0
  111. package/skills/tenjin-publish/SKILL.md +111 -0
  112. package/skills/tenjin-search/SKILL.md +133 -0
  113. package/dist/chunk-BRJHUQSY.js.map +0 -1
  114. package/dist/chunk-CUWUHTIL.js.map +0 -1
  115. package/dist/chunk-DXPYFVKG.js.map +0 -1
  116. package/dist/chunk-EXBMF5X7.js.map +0 -1
  117. package/dist/chunk-EZROUI5U.js.map +0 -1
  118. package/dist/chunk-IPOWB3G3.js.map +0 -1
  119. package/dist/chunk-LPRVHM7P.js.map +0 -1
  120. package/dist/chunk-T4LKNY7T.js.map +0 -1
  121. package/dist/chunk-ZPZFPVDN.js.map +0 -1
  122. package/dist/cli-WA65NP4Y.js.map +0 -1
  123. package/dist/config-CEFTL5ZL.js.map +0 -1
  124. package/dist/doctor-3QBYN46N.js.map +0 -1
  125. package/dist/usdc-44R6XZF2.js +0 -18
  126. package/dist/wallet-ELBTBMXO.js +0 -20
  127. /package/dist/{_esm-ZH2J4QEH.js.map → _esm-C5CRWCYU.js.map} +0 -0
  128. /package/dist/{ccip-UCLT5VOW.js.map → _esm-FEASBWRP.js.map} +0 -0
  129. /package/dist/{chunk-3IMLRUZE.js.map → ccip-NQXCEK2U.js.map} +0 -0
  130. /package/dist/{secp256k1-BEZS642W.js.map → ccip-XR5NE5QK.js.map} +0 -0
  131. /package/dist/{usdc-44R6XZF2.js.map → chunk-ZXTAQYNA.js.map} +0 -0
  132. /package/dist/{wallet-ELBTBMXO.js.map → config-VELDKLHY.js.map} +0 -0
  133. /package/dist/{mine.wasm-GQECMSGN.js.map → mine.wasm-6PIT3DK6.js.map} +0 -0
@@ -0,0 +1,126 @@
1
+ import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
2
+ import {
3
+ UUID_RE,
4
+ newId
5
+ } from "./chunk-3OV7E5G5.js";
6
+ import {
7
+ hasCode
8
+ } from "./chunk-2I4QTOLB.js";
9
+ import {
10
+ writeFileAtomicExclusive
11
+ } from "./chunk-MUBUQVC3.js";
12
+ import {
13
+ external_exports
14
+ } from "./chunk-OYMYCW7J.js";
15
+
16
+ // src/lib/candidate-store.ts
17
+ import { mkdir, readFile, readdir, rm, stat } from "fs/promises";
18
+ import { join } from "path";
19
+ var DRAFT_FILE = "draft.md";
20
+ var META_FILE = "meta.json";
21
+ var CandidateMetaSchema = external_exports.object({
22
+ schemaVersion: external_exports.literal(1),
23
+ lookupId: external_exports.string(),
24
+ question: external_exports.string().optional(),
25
+ // Fixed-width UTC ISO-8601 (a trailing Z, never an offset): listCandidates
26
+ // sorts newest-first lexicographically on this string, which is only a valid
27
+ // proxy for chronological order when every value is same-zone UTC. z.iso
28
+ // .datetime() rejects offsets and non-datetime strings, pinning that invariant.
29
+ created: external_exports.iso.datetime(),
30
+ /** The repo root the add ran in, or the cwd when not in a repo. */
31
+ sourceProject: external_exports.string()
32
+ });
33
+ function candidatesDir(dataDir) {
34
+ return join(dataDir, "candidates");
35
+ }
36
+ function candidateDir(dataDir, id) {
37
+ return join(candidatesDir(dataDir), id);
38
+ }
39
+ async function createCandidate(dataDir, input) {
40
+ const id = newId();
41
+ const dir = candidateDir(dataDir, id);
42
+ await mkdir(dir, { recursive: true, mode: 448 });
43
+ const draftPath = join(dir, DRAFT_FILE);
44
+ const meta = {
45
+ schemaVersion: 1,
46
+ lookupId: input.lookupId,
47
+ ...input.question !== void 0 ? { question: input.question } : {},
48
+ created: input.created,
49
+ sourceProject: input.sourceProject
50
+ };
51
+ try {
52
+ await writeFileAtomicExclusive(draftPath, input.draft, { mode: 384, dirMode: 448 });
53
+ await writeFileAtomicExclusive(join(dir, META_FILE), `${JSON.stringify(meta, null, 2)}
54
+ `, {
55
+ mode: 384,
56
+ dirMode: 448
57
+ });
58
+ } catch (err) {
59
+ if (!hasCode(err, "EEXIST")) {
60
+ await rm(dir, { recursive: true, force: true }).catch(() => void 0);
61
+ }
62
+ throw err;
63
+ }
64
+ return { id, meta, dir, draftPath };
65
+ }
66
+ async function readCandidate(dataDir, id) {
67
+ if (!UUID_RE.test(id)) return null;
68
+ const dir = candidateDir(dataDir, id);
69
+ const meta = await readMeta(dir);
70
+ if (meta === null) return null;
71
+ return { id, meta, dir, draftPath: join(dir, DRAFT_FILE) };
72
+ }
73
+ async function listCandidates(dataDir) {
74
+ let entries;
75
+ try {
76
+ entries = await readdir(candidatesDir(dataDir), { withFileTypes: true });
77
+ } catch {
78
+ return [];
79
+ }
80
+ const records = [];
81
+ for (const entry of entries) {
82
+ if (!entry.isDirectory() || !UUID_RE.test(entry.name)) continue;
83
+ const record = await readCandidate(dataDir, entry.name);
84
+ if (record !== null) records.push(record);
85
+ }
86
+ records.sort((a, b) => {
87
+ if (a.meta.created !== b.meta.created) return a.meta.created < b.meta.created ? 1 : -1;
88
+ return a.id < b.id ? 1 : -1;
89
+ });
90
+ return records;
91
+ }
92
+ async function dropCandidate(dataDir, id) {
93
+ if (!UUID_RE.test(id)) return false;
94
+ const dir = candidateDir(dataDir, id);
95
+ try {
96
+ if (!(await stat(dir)).isDirectory()) return false;
97
+ } catch {
98
+ return false;
99
+ }
100
+ await rm(dir, { recursive: true, force: true });
101
+ return true;
102
+ }
103
+ async function readMeta(dir) {
104
+ let raw;
105
+ try {
106
+ raw = await readFile(join(dir, META_FILE), "utf8");
107
+ } catch {
108
+ return null;
109
+ }
110
+ let json;
111
+ try {
112
+ json = JSON.parse(raw);
113
+ } catch {
114
+ return null;
115
+ }
116
+ const parsed = CandidateMetaSchema.safeParse(json);
117
+ return parsed.success ? parsed.data : null;
118
+ }
119
+
120
+ export {
121
+ createCandidate,
122
+ readCandidate,
123
+ listCandidates,
124
+ dropCandidate
125
+ };
126
+ //# sourceMappingURL=chunk-TLCMMYLY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/candidate-store.ts"],"sourcesContent":["import { mkdir, readFile, readdir, rm, stat } from 'node:fs/promises';\nimport type { Dirent } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport { writeFileAtomicExclusive } from './atomic-json';\nimport { hasCode } from './errno';\nimport { newId, UUID_RE } from './ids';\n\n/**\n * The D40 candidate store: publish drafts parked locally that never touch the\n * network and never upload — only a later `tenjin publish --candidate <id>`\n * sends one, under the D38 consent scan. Each candidate is its OWN directory\n * `~/.tenjin/candidates/<id>/` holding the draft markdown plus a meta.json.\n *\n * Custody mirrors the wallet key discipline: the candidates tree is 0700 and\n * every file 0600, written create-once through writeFileAtomicExclusive so a\n * reader sees a complete file or none and a uuid collision is loud, never a\n * silent overwrite. Unlike lookup-store's single shared ledger, there is no shared\n * mutable file here — a fresh uuid per add means two concurrent adds land in two\n * distinct dirs and cannot contend — so no cross-process lock is needed. The\n * meta.json is written LAST and atomically, making it the commit point: `list`\n * skips any dir whose meta is absent or unreadable, so a torn or half-written\n * add reads as not-yet-there rather than a broken candidate, the same\n * best-effort posture loadLookups takes on a corrupt store. A crash mid-add is\n * cleaned up eagerly (the dir is removed on any write failure), and `drop` can\n * still remove a metaless orphan by id so a leaked draft is never stranded.\n */\n\nconst DRAFT_FILE = 'draft.md';\nconst META_FILE = 'meta.json';\n\nconst CandidateMetaSchema = z.object({\n schemaVersion: z.literal(1),\n lookupId: z.string(),\n question: z.string().optional(),\n // Fixed-width UTC ISO-8601 (a trailing Z, never an offset): listCandidates\n // sorts newest-first lexicographically on this string, which is only a valid\n // proxy for chronological order when every value is same-zone UTC. z.iso\n // .datetime() rejects offsets and non-datetime strings, pinning that invariant.\n created: z.iso.datetime(),\n /** The repo root the add ran in, or the cwd when not in a repo. */\n sourceProject: z.string(),\n});\nexport type CandidateMeta = z.infer<typeof CandidateMetaSchema>;\n\nexport interface CandidateRecord {\n id: string;\n meta: CandidateMeta;\n /** Absolute path of the candidate directory. */\n dir: string;\n /** Absolute path of the draft markdown inside the directory. */\n draftPath: string;\n}\n\nexport interface CreateCandidateInput {\n /** The draft markdown, copied verbatim into the candidate. */\n draft: string;\n lookupId: string;\n question?: string;\n /** ISO-8601 creation time; the command supplies it via its clock seam. */\n created: string;\n sourceProject: string;\n}\n\nfunction candidatesDir(dataDir: string): string {\n return join(dataDir, 'candidates');\n}\n\nfunction candidateDir(dataDir: string, id: string): string {\n return join(candidatesDir(dataDir), id);\n}\n\n/** Park a draft as a new candidate and return the created record. Both files are\n * written create-once (no-clobber, fsynced) at a fresh uuid path, meta.json\n * last, so the candidate is either fully present to `list`/`read` or absent,\n * never half-there. */\nexport async function createCandidate(\n dataDir: string,\n input: CreateCandidateInput,\n): Promise<CandidateRecord> {\n const id = newId();\n const dir = candidateDir(dataDir, id);\n await mkdir(dir, { recursive: true, mode: 0o700 });\n\n const draftPath = join(dir, DRAFT_FILE);\n const meta: CandidateMeta = {\n schemaVersion: 1,\n lookupId: input.lookupId,\n ...(input.question !== undefined ? { question: input.question } : {}),\n created: input.created,\n sourceProject: input.sourceProject,\n };\n try {\n // Exclusive (create-or-EEXIST, fsynced) so a uuid collision is loud, not a\n // silent overwrite of an existing candidate, and the crash-durable commit of\n // meta.json is the last, atomic step.\n await writeFileAtomicExclusive(draftPath, input.draft, { mode: 0o600, dirMode: 0o700 });\n await writeFileAtomicExclusive(join(dir, META_FILE), `${JSON.stringify(meta, null, 2)}\\n`, {\n mode: 0o600,\n dirMode: 0o700,\n });\n } catch (err) {\n // An EEXIST means something already lived at this fresh-uuid path (a real\n // collision, astronomically unlikely): surface it loudly and NEVER delete\n // what was already there. Any other failure is a partial write of our own\n // fresh dir — remove it so a crash mid-add can't strand a hidden dir holding\n // the (secrets-adjacent) draft that `list` skips and no one can name to `drop`.\n if (!hasCode(err, 'EEXIST')) {\n await rm(dir, { recursive: true, force: true }).catch(() => undefined);\n }\n throw err;\n }\n\n return { id, meta, dir, draftPath };\n}\n\n/** One candidate by id, or null when it is unknown (or the id is malformed, so a\n * stray argument can never traverse out of the store). */\nexport async function readCandidate(dataDir: string, id: string): Promise<CandidateRecord | null> {\n if (!UUID_RE.test(id)) return null;\n const dir = candidateDir(dataDir, id);\n const meta = await readMeta(dir);\n if (meta === null) return null;\n return { id, meta, dir, draftPath: join(dir, DRAFT_FILE) };\n}\n\n/** Every pending candidate, newest first by `created` (no auto-expiry — stale\n * candidates stay visible, D40). Tie-broken on id so the order is total. */\nexport async function listCandidates(dataDir: string): Promise<CandidateRecord[]> {\n let entries: Dirent[];\n try {\n entries = await readdir(candidatesDir(dataDir), { withFileTypes: true });\n } catch {\n return [];\n }\n const records: CandidateRecord[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory() || !UUID_RE.test(entry.name)) continue;\n const record = await readCandidate(dataDir, entry.name);\n if (record !== null) records.push(record);\n }\n records.sort((a, b) => {\n if (a.meta.created !== b.meta.created) return a.meta.created < b.meta.created ? 1 : -1;\n return a.id < b.id ? 1 : -1;\n });\n return records;\n}\n\n/** Discard one candidate by id. Returns false when the id is malformed or no\n * such dir exists, so the command can surface a clean not-found; nothing is\n * ever auto-deleted. Removes the dir even when its meta is absent or corrupt,\n * so a crash-orphaned candidate can still be cleaned up by id (the id is\n * UUID-gated first, so a stray argument can never target a path outside the\n * store). */\nexport async function dropCandidate(dataDir: string, id: string): Promise<boolean> {\n if (!UUID_RE.test(id)) return false;\n const dir = candidateDir(dataDir, id);\n try {\n if (!(await stat(dir)).isDirectory()) return false;\n } catch {\n return false; // no such candidate\n }\n await rm(dir, { recursive: true, force: true });\n return true;\n}\n\n/** Read and validate a candidate's meta.json; null on any absence/corruption. */\nasync function readMeta(dir: string): Promise<CandidateMeta | null> {\n let raw: string;\n try {\n raw = await readFile(join(dir, META_FILE), 'utf8');\n } catch {\n return null;\n }\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch {\n return null;\n }\n const parsed = CandidateMetaSchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n}\n"],"mappings":"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","names":[]}