dero-mcp-server 0.1.1 → 0.2.2

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 (58) hide show
  1. package/README.md +79 -6
  2. package/data/docs-index.json +5702 -0
  3. package/dist/citations.d.ts +70 -0
  4. package/dist/citations.d.ts.map +1 -0
  5. package/dist/citations.js +162 -0
  6. package/dist/citations.js.map +1 -0
  7. package/dist/composites/_shared.d.ts +119 -0
  8. package/dist/composites/_shared.d.ts.map +1 -0
  9. package/dist/composites/_shared.js +152 -0
  10. package/dist/composites/_shared.js.map +1 -0
  11. package/dist/composites/diagnose-chain-health.d.ts +64 -0
  12. package/dist/composites/diagnose-chain-health.d.ts.map +1 -0
  13. package/dist/composites/diagnose-chain-health.js +144 -0
  14. package/dist/composites/diagnose-chain-health.js.map +1 -0
  15. package/dist/composites/estimate-deploy-cost.d.ts +83 -0
  16. package/dist/composites/estimate-deploy-cost.d.ts.map +1 -0
  17. package/dist/composites/estimate-deploy-cost.js +116 -0
  18. package/dist/composites/estimate-deploy-cost.js.map +1 -0
  19. package/dist/composites/explain-smart-contract.d.ts +64 -0
  20. package/dist/composites/explain-smart-contract.d.ts.map +1 -0
  21. package/dist/composites/explain-smart-contract.js +149 -0
  22. package/dist/composites/explain-smart-contract.js.map +1 -0
  23. package/dist/composites/recommend-docs-path.d.ts +97 -0
  24. package/dist/composites/recommend-docs-path.d.ts.map +1 -0
  25. package/dist/composites/recommend-docs-path.js +149 -0
  26. package/dist/composites/recommend-docs-path.js.map +1 -0
  27. package/dist/composites/trace-transaction-with-context.d.ts +107 -0
  28. package/dist/composites/trace-transaction-with-context.d.ts.map +1 -0
  29. package/dist/composites/trace-transaction-with-context.js +217 -0
  30. package/dist/composites/trace-transaction-with-context.js.map +1 -0
  31. package/dist/docs-parse.d.ts +30 -0
  32. package/dist/docs-parse.d.ts.map +1 -0
  33. package/dist/docs-parse.js +147 -0
  34. package/dist/docs-parse.js.map +1 -0
  35. package/dist/docs.d.ts +101 -0
  36. package/dist/docs.d.ts.map +1 -0
  37. package/dist/docs.js +172 -0
  38. package/dist/docs.js.map +1 -0
  39. package/dist/server.d.ts.map +1 -1
  40. package/dist/server.js +417 -100
  41. package/dist/server.js.map +1 -1
  42. package/dist/tool-descriptions.d.ts +50 -0
  43. package/dist/tool-descriptions.d.ts.map +1 -0
  44. package/dist/tool-descriptions.js +246 -0
  45. package/dist/tool-descriptions.js.map +1 -0
  46. package/package.json +15 -3
  47. package/.github/workflows/ci.yml +0 -62
  48. package/docs/example-agent-flows.md +0 -236
  49. package/docs/mcp-agent-ready-evidence.md +0 -108
  50. package/glama.json +0 -6
  51. package/scripts/doctor.sh +0 -85
  52. package/scripts/flow-test.ts +0 -257
  53. package/scripts/mcp-smoke-probes.ts +0 -168
  54. package/server.json +0 -23
  55. package/src/index.ts +0 -30
  56. package/src/rpc.ts +0 -60
  57. package/src/server.ts +0 -636
  58. package/tsconfig.json +0 -16
@@ -0,0 +1,97 @@
1
+ /**
2
+ * `recommend_docs_path` — Phase C composite #3.
3
+ *
4
+ * Docs-only composite. Takes a natural-language intent, runs scoped
5
+ * searches across ALL four products in parallel, boosts
6
+ * hint-matching scores by 1.5× (when `product_hint` is provided),
7
+ * groups results by product, and returns a ranked path with
8
+ * per-result rationale and ready-to-cite citations.
9
+ *
10
+ * Wedge: agents currently have to guess which docs product to search
11
+ * (derod for daemon RPC, tela for on-chain apps, hologram for the
12
+ * simulator, deropay for the merchant flow). This composite removes
13
+ * that guess: one call, one ranked answer, with citations the agent
14
+ * can drop straight into a response.
15
+ *
16
+ * Design contract: `docs/composites.md` § 3. Sequencing rule: SHIP
17
+ * THIRD. Pure docs composition — no chain reads. Proves the
18
+ * "docs-only composite" pattern that future docs-heavy tools can
19
+ * reuse.
20
+ *
21
+ * Design clarification: the spec text "for each product (or just
22
+ * `product_hint` if provided)" reads like a filter, but the spec's
23
+ * scoring rule ("score by `score * productHintBoost` for hint
24
+ * matches") only makes sense if all four products are always
25
+ * searched and the hint is treated as a BIAS, not a FILTER. Treating
26
+ * the hint as a filter would make the boost a uniform no-op. This
27
+ * implementation searches all four products on every call so the
28
+ * hint scoring carries real weight and the agent still sees relevant
29
+ * cross-product docs (e.g. derod RPC pages that touch TELA).
30
+ *
31
+ * Failure model:
32
+ * - Zero matches across every product → throw
33
+ * `'No DERO docs matched intent: "..."'`. The `withStructuredErrors`
34
+ * wrapper classifies this as `NO_DOCS_MATCH` and emits a hint
35
+ * telling the agent to rephrase (or change the `product_hint`).
36
+ * - The bundled docs index missing → propagates the existing
37
+ * `DOCS_UNAVAILABLE` classification from `searchDeroDocs`.
38
+ */
39
+ import { z } from 'zod';
40
+ import { type DeroDocProduct } from '../docs.js';
41
+ import { type DeroCitation } from '../citations.js';
42
+ export declare const recommendDocsPathInputSchema: {
43
+ readonly intent: z.ZodString;
44
+ readonly product_hint: z.ZodOptional<z.ZodEnum<["derod", "tela", "hologram", "deropay"]>>;
45
+ readonly limit_per_product: z.ZodOptional<z.ZodNumber>;
46
+ };
47
+ type RecommendInput = {
48
+ intent: string;
49
+ product_hint?: DeroDocProduct;
50
+ limit_per_product?: number;
51
+ };
52
+ /**
53
+ * Per-result shape returned by `searchDeroDocs`. Re-declared here as the
54
+ * minimum surface the composite touches so this module stays decoupled
55
+ * from internal changes to the docs search response.
56
+ */
57
+ type SearchHit = {
58
+ product: DeroDocProduct;
59
+ slug: string;
60
+ title: string;
61
+ description?: string;
62
+ canonical_url: string;
63
+ headings: string[];
64
+ excerpt: string;
65
+ score: number;
66
+ };
67
+ type Recommendation = {
68
+ product: DeroDocProduct;
69
+ slug: string;
70
+ title: string;
71
+ canonical_url: string;
72
+ score: number;
73
+ boosted_score: number;
74
+ rationale: string;
75
+ };
76
+ type ByProductSummary = Record<DeroDocProduct, {
77
+ count: number;
78
+ top_slug: string | null;
79
+ top_score: number | null;
80
+ }>;
81
+ /**
82
+ * Pure helper: turn raw per-product hits into a ranked, deduplicated
83
+ * list with boosted scores and rationale strings. Exported so flow
84
+ * tests / future unit tests can call it without spinning up an MCP
85
+ * client.
86
+ */
87
+ export declare function rankRecommendations(intent: string, productHint: DeroDocProduct | undefined, hitsByProduct: ReadonlyMap<DeroDocProduct, readonly SearchHit[]>): Recommendation[];
88
+ export declare function recommendDocsPath(args: RecommendInput): Promise<{
89
+ intent: string;
90
+ product_hint: "derod" | "tela" | "hologram" | "deropay" | null;
91
+ limit_per_product: number;
92
+ recommended: Recommendation[];
93
+ by_product: ByProductSummary;
94
+ related_docs: DeroCitation[];
95
+ }>;
96
+ export {};
97
+ //# sourceMappingURL=recommend-docs-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend-docs-path.d.ts","sourceRoot":"","sources":["../../src/composites/recommend-docs-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAItE,eAAO,MAAM,4BAA4B;;;;CAkB/B,CAAA;AAEV,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,cAAc,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;;GAIG;AACH,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,gBAAgB,GAAG,MAAM,CAC5B,cAAc,EACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CACrE,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,cAAc,GAAG,SAAS,EACvC,aAAa,EAAE,WAAW,CAAC,cAAc,EAAE,SAAS,SAAS,EAAE,CAAC,GAC/D,cAAc,EAAE,CA2BlB;AA4CD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,cAAc;;;;;;;GAsC3D"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * `recommend_docs_path` — Phase C composite #3.
3
+ *
4
+ * Docs-only composite. Takes a natural-language intent, runs scoped
5
+ * searches across ALL four products in parallel, boosts
6
+ * hint-matching scores by 1.5× (when `product_hint` is provided),
7
+ * groups results by product, and returns a ranked path with
8
+ * per-result rationale and ready-to-cite citations.
9
+ *
10
+ * Wedge: agents currently have to guess which docs product to search
11
+ * (derod for daemon RPC, tela for on-chain apps, hologram for the
12
+ * simulator, deropay for the merchant flow). This composite removes
13
+ * that guess: one call, one ranked answer, with citations the agent
14
+ * can drop straight into a response.
15
+ *
16
+ * Design contract: `docs/composites.md` § 3. Sequencing rule: SHIP
17
+ * THIRD. Pure docs composition — no chain reads. Proves the
18
+ * "docs-only composite" pattern that future docs-heavy tools can
19
+ * reuse.
20
+ *
21
+ * Design clarification: the spec text "for each product (or just
22
+ * `product_hint` if provided)" reads like a filter, but the spec's
23
+ * scoring rule ("score by `score * productHintBoost` for hint
24
+ * matches") only makes sense if all four products are always
25
+ * searched and the hint is treated as a BIAS, not a FILTER. Treating
26
+ * the hint as a filter would make the boost a uniform no-op. This
27
+ * implementation searches all four products on every call so the
28
+ * hint scoring carries real weight and the agent still sees relevant
29
+ * cross-product docs (e.g. derod RPC pages that touch TELA).
30
+ *
31
+ * Failure model:
32
+ * - Zero matches across every product → throw
33
+ * `'No DERO docs matched intent: "..."'`. The `withStructuredErrors`
34
+ * wrapper classifies this as `NO_DOCS_MATCH` and emits a hint
35
+ * telling the agent to rephrase (or change the `product_hint`).
36
+ * - The bundled docs index missing → propagates the existing
37
+ * `DOCS_UNAVAILABLE` classification from `searchDeroDocs`.
38
+ */
39
+ import { z } from 'zod';
40
+ import { DERO_DOC_PRODUCTS, searchDeroDocs, } from '../docs.js';
41
+ import { buildDeroCitation } from '../citations.js';
42
+ const PRODUCT_HINT_BOOST = 1.5;
43
+ export const recommendDocsPathInputSchema = {
44
+ intent: z
45
+ .string()
46
+ .min(8)
47
+ .describe('Natural-language description of what the user wants to do (e.g. "deploy a TELA app", "trace a transaction by hash", "verify a webhook signature").'),
48
+ product_hint: z
49
+ .enum(DERO_DOC_PRODUCTS)
50
+ .optional()
51
+ .describe('Optional bias toward one product (derod | tela | hologram | deropay) when known.'),
52
+ limit_per_product: z
53
+ .number()
54
+ .int()
55
+ .min(1)
56
+ .max(5)
57
+ .optional()
58
+ .describe('Cap per-product search results before merging. Default 2.'),
59
+ };
60
+ /**
61
+ * Pure helper: turn raw per-product hits into a ranked, deduplicated
62
+ * list with boosted scores and rationale strings. Exported so flow
63
+ * tests / future unit tests can call it without spinning up an MCP
64
+ * client.
65
+ */
66
+ export function rankRecommendations(intent, productHint, hitsByProduct) {
67
+ const out = [];
68
+ const seen = new Set();
69
+ for (const [product, hits] of hitsByProduct) {
70
+ for (const hit of hits) {
71
+ const key = `${product}::${hit.slug}`;
72
+ if (seen.has(key))
73
+ continue;
74
+ seen.add(key);
75
+ const boost = product === productHint ? PRODUCT_HINT_BOOST : 1;
76
+ const boostedScore = Math.round(hit.score * boost * 100) / 100;
77
+ const topHeading = hit.headings[0];
78
+ const rationale = buildRationale(intent, product, hit.score, boost, topHeading);
79
+ out.push({
80
+ product,
81
+ slug: hit.slug,
82
+ title: hit.title,
83
+ canonical_url: hit.canonical_url,
84
+ score: hit.score,
85
+ boosted_score: boostedScore,
86
+ rationale,
87
+ });
88
+ }
89
+ }
90
+ out.sort((a, b) => b.boosted_score - a.boosted_score);
91
+ return out;
92
+ }
93
+ function buildRationale(intent, product, rawScore, boost, topHeading) {
94
+ const boostNote = boost > 1 ? ` (×${boost} product_hint boost applied)` : '';
95
+ const headingPart = topHeading ? ` Top heading: "${topHeading.slice(0, 80)}".` : '';
96
+ return `Match for "${intent.slice(0, 60)}" under product=${product} (raw score ${rawScore}${boostNote}).${headingPart}`;
97
+ }
98
+ function summarizeByProduct(recs) {
99
+ const out = Object.create(null);
100
+ for (const product of DERO_DOC_PRODUCTS) {
101
+ out[product] = { count: 0, top_slug: null, top_score: null };
102
+ }
103
+ for (const rec of recs) {
104
+ const bucket = out[rec.product];
105
+ bucket.count += 1;
106
+ if (bucket.top_score === null || rec.boosted_score > bucket.top_score) {
107
+ bucket.top_score = rec.boosted_score;
108
+ bucket.top_slug = rec.slug;
109
+ }
110
+ }
111
+ return out;
112
+ }
113
+ /**
114
+ * Build top-N citations from the ranked recommendations. Always
115
+ * deduplicated by `product::slug` (which `rankRecommendations` also
116
+ * enforces) so the citation list never lists the same page twice.
117
+ */
118
+ function citationsFromRecommendations(recs, topN) {
119
+ return recs
120
+ .slice(0, topN)
121
+ .map((rec) => buildDeroCitation(rec.product, rec.slug, rec.title));
122
+ }
123
+ export async function recommendDocsPath(args) {
124
+ const intent = args.intent.trim();
125
+ const limitPerProduct = args.limit_per_product ?? 2;
126
+ const productHint = args.product_hint;
127
+ // Always fan out to all four products. `searchDeroDocs` shares an
128
+ // in-process page cache (15s TTL) so the second+ calls in the batch
129
+ // resolve from memory; the network/disk cost is paid once per cache
130
+ // window. See the module header for why we don't filter to
131
+ // product_hint.
132
+ const searches = await Promise.all(DERO_DOC_PRODUCTS.map((product) => searchDeroDocs({ query: intent, product, limit: limitPerProduct }).then((res) => [product, res.results])));
133
+ const hitsByProduct = new Map(searches);
134
+ const recommended = rankRecommendations(intent, productHint, hitsByProduct);
135
+ if (recommended.length === 0) {
136
+ throw new Error(`No DERO docs matched intent: "${intent}" across products: ${DERO_DOC_PRODUCTS.join(', ')}. Try rephrasing with product-specific nouns (e.g. "TELA INDEX-1 contract", "DeroPay webhook").`);
137
+ }
138
+ const by_product = summarizeByProduct(recommended);
139
+ const related_docs = citationsFromRecommendations(recommended, 2);
140
+ return {
141
+ intent,
142
+ product_hint: productHint ?? null,
143
+ limit_per_product: limitPerProduct,
144
+ recommended,
145
+ by_product,
146
+ related_docs,
147
+ };
148
+ }
149
+ //# sourceMappingURL=recommend-docs-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend-docs-path.js","sourceRoot":"","sources":["../../src/composites/recommend-docs-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * `trace_transaction_with_context` — Phase C composite #5 (final).
3
+ *
4
+ * Wedge: `dero_get_transaction` returns the raw tx record (block,
5
+ * ring, signer, code, balances) but leaves the agent to figure out
6
+ * confirmation state, classify the tx kind, and separately fetch
7
+ * any SC context. This composite combines all of that in one call
8
+ * and stitches the right docs page as a citation.
9
+ *
10
+ * Design contract: `docs/composites.md` § 5. Sequencing rule: SHIP
11
+ * LAST — highest fan-out + failure-mode count of all Phase C
12
+ * composites.
13
+ *
14
+ * Implementation notes (recorded honestly so the design doc and
15
+ * shipped surface stay in sync):
16
+ *
17
+ * - SC INSTALL detection works directly off the tx record: when
18
+ * `tx.code` is non-empty the tx_hash itself IS the resulting
19
+ * SCID and the embedded code is the deployed source. We run
20
+ * `extractScSurface` on `tx.code` directly — no second
21
+ * `DERO.GetSC` call is needed for installs.
22
+ * - SC INVOCATION arg/entrypoint decoding requires walking the
23
+ * binary tx blob (`txs_as_hex`) with DERO's tx codec. That
24
+ * codec is not yet bundled in this MCP, so the composite does
25
+ * NOT fabricate decoded args. It surfaces `raw_tx_hex_length`
26
+ * so the agent knows the binary is available via
27
+ * `dero_get_transaction` if a downstream wallet wants to
28
+ * decode it.
29
+ * - TX_NOT_FOUND is signalled by the daemon as an EMPTY record
30
+ * (`block_height: 0, in_pool: false, code: ''`) — it does
31
+ * not throw. The composite detects this and throws a
32
+ * classifier-friendly message so `withStructuredErrors`
33
+ * surfaces `_meta.error.code = TX_NOT_FOUND`.
34
+ *
35
+ * Failure model:
36
+ * - `DERO.GetTransaction` throws → propagates via
37
+ * `withStructuredErrors` (RPC_UNREACHABLE / RPC_INVALID_PARAMS
38
+ * classifier branches handle the daemon-side cases).
39
+ * - Daemon returns empty record for the hash → composite throws
40
+ * `'DERO transaction not found: ...'` → classifier returns
41
+ * `TX_NOT_FOUND` with a retry hint.
42
+ * - Tx found but SC surface extraction degraded for the install
43
+ * case → record the surface as-is (`has_code: false`,
44
+ * `functions: []`) and let the narrative explain. Never abort.
45
+ */
46
+ import { z } from 'zod';
47
+ import { type DeroDaemonRpc } from './_shared.js';
48
+ export declare const traceTransactionWithContextInputSchema: {
49
+ readonly tx_hash: z.ZodString;
50
+ readonly decode: z.ZodOptional<z.ZodBoolean>;
51
+ readonly include_sc_context: z.ZodOptional<z.ZodBoolean>;
52
+ };
53
+ type TraceInput = {
54
+ tx_hash: string;
55
+ decode?: boolean;
56
+ include_sc_context?: boolean;
57
+ };
58
+ type ConfirmationStatus = 'confirmed' | 'mempool' | 'unknown';
59
+ type TxKind = 'sc_install' | 'transfer_or_invocation' | 'coinbase' | 'unknown';
60
+ export declare function traceTransactionWithContext(rpc: DeroDaemonRpc, args: TraceInput): Promise<{
61
+ tx_hash: string;
62
+ confirmation: {
63
+ status: ConfirmationStatus;
64
+ block_height: number | null;
65
+ valid_block: string | null;
66
+ invalid_blocks: string[];
67
+ in_pool: boolean;
68
+ };
69
+ kind: TxKind;
70
+ ring: {
71
+ groups: number | null;
72
+ first_group_size: number | null;
73
+ };
74
+ reward: number | null;
75
+ signer_visible: boolean;
76
+ native_balance: {
77
+ scid: string;
78
+ at_tx: number | null;
79
+ current: number | null;
80
+ };
81
+ sc_install: {
82
+ scid: string;
83
+ surface: {
84
+ functions: import("./_shared.js").DvmFunctionSignature[];
85
+ stringkeys: string[];
86
+ uint64keys: string[];
87
+ balances: Record<string, string | number>;
88
+ };
89
+ raw_code_length: number;
90
+ has_code: boolean;
91
+ } | null;
92
+ raw_tx_hex_length: number;
93
+ narrative: string;
94
+ _diagnostics: {
95
+ step_latency_ms: Record<string, number>;
96
+ total_ms: number;
97
+ halted_at: string | null;
98
+ decode_as_json: boolean;
99
+ include_sc_context: boolean;
100
+ sc_install_surface_attempted: boolean;
101
+ sc_install_surface_failed: boolean;
102
+ };
103
+ } & {
104
+ related_docs?: import("../citations.js").DeroCitation[];
105
+ }>;
106
+ export {};
107
+ //# sourceMappingURL=trace-transaction-with-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-transaction-with-context.d.ts","sourceRoot":"","sources":["../../src/composites/trace-transaction-with-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,cAAc,CAAA;AAKrB,eAAO,MAAM,sCAAsC;;;;CAezC,CAAA;AAEV,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AA6BD,KAAK,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAA;AAC7D,KAAK,MAAM,GAAG,YAAY,GAAG,wBAAwB,GAAG,UAAU,GAAG,SAAS,CAAA;AAgF9E,wBAAsB,2BAA2B,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GrF"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * `trace_transaction_with_context` — Phase C composite #5 (final).
3
+ *
4
+ * Wedge: `dero_get_transaction` returns the raw tx record (block,
5
+ * ring, signer, code, balances) but leaves the agent to figure out
6
+ * confirmation state, classify the tx kind, and separately fetch
7
+ * any SC context. This composite combines all of that in one call
8
+ * and stitches the right docs page as a citation.
9
+ *
10
+ * Design contract: `docs/composites.md` § 5. Sequencing rule: SHIP
11
+ * LAST — highest fan-out + failure-mode count of all Phase C
12
+ * composites.
13
+ *
14
+ * Implementation notes (recorded honestly so the design doc and
15
+ * shipped surface stay in sync):
16
+ *
17
+ * - SC INSTALL detection works directly off the tx record: when
18
+ * `tx.code` is non-empty the tx_hash itself IS the resulting
19
+ * SCID and the embedded code is the deployed source. We run
20
+ * `extractScSurface` on `tx.code` directly — no second
21
+ * `DERO.GetSC` call is needed for installs.
22
+ * - SC INVOCATION arg/entrypoint decoding requires walking the
23
+ * binary tx blob (`txs_as_hex`) with DERO's tx codec. That
24
+ * codec is not yet bundled in this MCP, so the composite does
25
+ * NOT fabricate decoded args. It surfaces `raw_tx_hex_length`
26
+ * so the agent knows the binary is available via
27
+ * `dero_get_transaction` if a downstream wallet wants to
28
+ * decode it.
29
+ * - TX_NOT_FOUND is signalled by the daemon as an EMPTY record
30
+ * (`block_height: 0, in_pool: false, code: ''`) — it does
31
+ * not throw. The composite detects this and throws a
32
+ * classifier-friendly message so `withStructuredErrors`
33
+ * surfaces `_meta.error.code = TX_NOT_FOUND`.
34
+ *
35
+ * Failure model:
36
+ * - `DERO.GetTransaction` throws → propagates via
37
+ * `withStructuredErrors` (RPC_UNREACHABLE / RPC_INVALID_PARAMS
38
+ * classifier branches handle the daemon-side cases).
39
+ * - Daemon returns empty record for the hash → composite throws
40
+ * `'DERO transaction not found: ...'` → classifier returns
41
+ * `TX_NOT_FOUND` with a retry hint.
42
+ * - Tx found but SC surface extraction degraded for the install
43
+ * case → record the surface as-is (`has_code: false`,
44
+ * `functions: []`) and let the narrative explain. Never abort.
45
+ */
46
+ import { z } from 'zod';
47
+ import { attachCitations, extractScSurface, runChain, stepLatencies, stepValue, } from './_shared.js';
48
+ const HEX64_REGEX = /^[0-9a-fA-F]{64}$/;
49
+ const NATIVE_DERO_SCID = '0000000000000000000000000000000000000000000000000000000000000000';
50
+ export const traceTransactionWithContextInputSchema = {
51
+ tx_hash: z
52
+ .string()
53
+ .regex(HEX64_REGEX, 'Expected 64-character hex transaction hash')
54
+ .describe('64-char hex transaction hash'),
55
+ decode: z
56
+ .boolean()
57
+ .optional()
58
+ .describe('Pass decode_as_json=1 to the daemon. Default true. Decoded JSON view is informational; the raw hex always comes back.'),
59
+ include_sc_context: z
60
+ .boolean()
61
+ .optional()
62
+ .describe('When true (default), runs the SC-install surface extraction inline when the tx contains contract code. SC invocation arg decoding is NOT performed in either mode; see module docs.'),
63
+ };
64
+ function classifyConfirmation(tx) {
65
+ if (tx.in_pool === true)
66
+ return 'mempool';
67
+ if (typeof tx.block_height === 'number' && tx.block_height > 0)
68
+ return 'confirmed';
69
+ return 'unknown';
70
+ }
71
+ function classifyKind(tx) {
72
+ if (typeof tx.code === 'string' && tx.code.length > 0)
73
+ return 'sc_install';
74
+ if (typeof tx.reward === 'number' && tx.reward > 0 && (!tx.ring || tx.ring.length === 0)) {
75
+ return 'coinbase';
76
+ }
77
+ if (Array.isArray(tx.ring) && tx.ring.length > 0)
78
+ return 'transfer_or_invocation';
79
+ return 'unknown';
80
+ }
81
+ function ringStats(tx) {
82
+ if (!Array.isArray(tx.ring) || tx.ring.length === 0) {
83
+ return { groups: null, first_group_size: null };
84
+ }
85
+ const groups = tx.ring.length;
86
+ const first = tx.ring[0];
87
+ const firstSize = Array.isArray(first) ? first.length : null;
88
+ return { groups, first_group_size: firstSize };
89
+ }
90
+ function isEmptyTxRecord(tx) {
91
+ if (!tx)
92
+ return true;
93
+ const noBlock = !tx.block_height || tx.block_height === 0;
94
+ const noPool = tx.in_pool !== true;
95
+ const noCode = !tx.code || tx.code.length === 0;
96
+ const noRing = !Array.isArray(tx.ring) || tx.ring.length === 0;
97
+ return noBlock && noPool && noCode && noRing;
98
+ }
99
+ function buildNarrative(txHash, confirmation, kind, blockHeight, scInstallSurface, ringGroups, rawHexLen, scLookupFailed) {
100
+ const parts = [];
101
+ if (confirmation === 'mempool') {
102
+ parts.push(`Tx ${txHash} is in the mempool (not yet confirmed). It may still be reorganized or dropped; treat the result as provisional.`);
103
+ }
104
+ else if (confirmation === 'confirmed') {
105
+ parts.push(`Tx ${txHash} is confirmed at block height ${blockHeight ?? 'unknown'}.`);
106
+ }
107
+ else {
108
+ parts.push(`Tx ${txHash} confirmation status is unknown — the daemon returned a record but did not mark it confirmed or in mempool.`);
109
+ }
110
+ if (kind === 'sc_install') {
111
+ if (scInstallSurface && scInstallSurface.has_code) {
112
+ const fnCount = scInstallSurface.functions.length;
113
+ const sampleFns = scInstallSurface.functions
114
+ .slice(0, 4)
115
+ .map((f) => f.name)
116
+ .join(', ');
117
+ parts.push(`Tx is a smart-contract INSTALL: the tx_hash is the resulting SCID. The deployed source carries ${fnCount} function${fnCount === 1 ? '' : 's'}${sampleFns ? ` (${sampleFns}${fnCount > 4 ? ', …' : ''})` : ''}. The composite parsed the surface inline from the embedded code; no second dero_get_sc call was needed.`);
118
+ }
119
+ else if (scLookupFailed) {
120
+ parts.push('Tx is a smart-contract INSTALL but the surface extractor failed to parse the embedded code. Fall back to dero_get_sc with the tx_hash as SCID for the raw payload.');
121
+ }
122
+ }
123
+ else if (kind === 'coinbase') {
124
+ parts.push('Tx is a coinbase (mining reward) — no ring members, signer is the miner address.');
125
+ }
126
+ else if (kind === 'transfer_or_invocation') {
127
+ parts.push(`Tx is a transfer or SC invocation. ${ringGroups ? `${ringGroups} input ring group${ringGroups === 1 ? '' : 's'} present.` : ''} SC invocation arg decoding is not surfaced by the daemon's JSON response; the ${rawHexLen}-char raw hex blob is available via dero_get_transaction if a wallet-side decoder is needed.`);
128
+ }
129
+ return parts.join(' ');
130
+ }
131
+ export async function traceTransactionWithContext(rpc, args) {
132
+ const decode = args.decode !== false;
133
+ const includeScContext = args.include_sc_context !== false;
134
+ const params = {
135
+ txs_hashes: [args.tx_hash],
136
+ decode_as_json: decode ? 1 : 0,
137
+ };
138
+ const steps = [
139
+ {
140
+ name: 'get_transaction',
141
+ required: true,
142
+ fn: () => rpc('DERO.GetTransaction', params),
143
+ },
144
+ ];
145
+ const chain = await runChain(steps);
146
+ const txResult = stepValue(chain, 'get_transaction');
147
+ const tx = txResult?.txs?.[0];
148
+ const rawHexLen = (txResult?.txs_as_hex?.[0] ?? '').length;
149
+ if (!tx || isEmptyTxRecord(tx)) {
150
+ // Daemon does not error on unknown hashes — it returns an empty record.
151
+ // Throw a classifier-friendly message so withStructuredErrors emits
152
+ // TX_NOT_FOUND.
153
+ throw new Error(`DERO transaction not found: ${args.tx_hash}. The daemon returned an empty record (no block_height, no mempool entry, no code, no ring).`);
154
+ }
155
+ const confirmation = classifyConfirmation(tx);
156
+ const kind = classifyKind(tx);
157
+ const { groups: ringGroups, first_group_size: firstRingSize } = ringStats(tx);
158
+ let scInstallSurface = null;
159
+ let scLookupFailed = false;
160
+ if (includeScContext && kind === 'sc_install') {
161
+ try {
162
+ scInstallSurface = extractScSurface({ code: tx.code });
163
+ }
164
+ catch {
165
+ scLookupFailed = true;
166
+ scInstallSurface = null;
167
+ }
168
+ }
169
+ const narrative = buildNarrative(args.tx_hash, confirmation, kind, typeof tx.block_height === 'number' ? tx.block_height : null, scInstallSurface, ringGroups, rawHexLen, scLookupFailed);
170
+ return attachCitations({
171
+ tx_hash: args.tx_hash,
172
+ confirmation: {
173
+ status: confirmation,
174
+ block_height: typeof tx.block_height === 'number' ? tx.block_height : null,
175
+ valid_block: typeof tx.valid_block === 'string' && tx.valid_block.length > 0 ? tx.valid_block : null,
176
+ invalid_blocks: Array.isArray(tx.invalid_block) ? tx.invalid_block : [],
177
+ in_pool: tx.in_pool === true,
178
+ },
179
+ kind,
180
+ ring: {
181
+ groups: ringGroups,
182
+ first_group_size: firstRingSize,
183
+ },
184
+ reward: typeof tx.reward === 'number' ? tx.reward : null,
185
+ signer_visible: typeof tx.signer === 'string' && tx.signer.length > 0,
186
+ native_balance: {
187
+ scid: NATIVE_DERO_SCID,
188
+ at_tx: typeof tx.balance === 'number' ? tx.balance : null,
189
+ current: typeof tx.balancenow === 'number' ? tx.balancenow : null,
190
+ },
191
+ sc_install: scInstallSurface
192
+ ? {
193
+ scid: args.tx_hash,
194
+ surface: {
195
+ functions: scInstallSurface.functions,
196
+ stringkeys: scInstallSurface.stringkeys,
197
+ uint64keys: scInstallSurface.uint64keys,
198
+ balances: scInstallSurface.balances,
199
+ },
200
+ raw_code_length: scInstallSurface.raw_code_length,
201
+ has_code: scInstallSurface.has_code,
202
+ }
203
+ : null,
204
+ raw_tx_hex_length: rawHexLen,
205
+ narrative,
206
+ _diagnostics: {
207
+ step_latency_ms: stepLatencies(chain),
208
+ total_ms: chain.totalMs,
209
+ halted_at: chain.haltedAt,
210
+ decode_as_json: decode,
211
+ include_sc_context: includeScContext,
212
+ sc_install_surface_attempted: includeScContext && kind === 'sc_install',
213
+ sc_install_surface_failed: scLookupFailed,
214
+ },
215
+ }, 'trace_transaction_with_context');
216
+ }
217
+ //# sourceMappingURL=trace-transaction-with-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-transaction-with-context.js","sourceRoot":"","sources":["../../src/composites/trace-transaction-with-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,aAAa,EACb,SAAS,GAIV,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,GAAG,mBAAmB,CAAA;AACvC,MAAM,gBAAgB,GAAG,kEAAkE,CAAA;AAE3F,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,WAAW,EAAE,4CAA4C,CAAC;SAChE,QAAQ,CAAC,8BAA8B,CAAC;IAC3C,MAAM,EAAE,CAAC;SACN,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,uHAAuH,CAAC;IACpI,kBAAkB,EAAE,CAAC;SAClB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,qLAAqL,CACtL;CACK,CAAA;AAsCV,SAAS,oBAAoB,CAAC,EAAgB;IAC5C,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACzC,IAAI,OAAO,EAAE,CAAC,YAAY,KAAK,QAAQ,IAAI,EAAE,CAAC,YAAY,GAAG,CAAC;QAAE,OAAO,WAAW,CAAA;IAClF,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,EAAgB;IACpC,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,YAAY,CAAA;IAC1E,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACzF,OAAO,UAAU,CAAA;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,wBAAwB,CAAA;IACjF,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,EAAgB;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAA;IACjD,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAA;IAC7B,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5D,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAA;AAChD,CAAC;AAED,SAAS,eAAe,CAAC,EAA4B;IACnD,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACpB,MAAM,OAAO,GAAG,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,YAAY,KAAK,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,KAAK,IAAI,CAAA;IAClC,MAAM,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAA;IAC9D,OAAO,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAA;AAC9C,CAAC;AAED,SAAS,cAAc,CACrB,MAAc,EACd,YAAgC,EAChC,IAAY,EACZ,WAA0B,EAC1B,gBAAsC,EACtC,UAAyB,EACzB,SAAiB,EACjB,cAAuB;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,kHAAkH,CAAC,CAAA;IAC5I,CAAC;SAAM,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,iCAAiC,WAAW,IAAI,SAAS,GAAG,CAAC,CAAA;IACtF,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,6GAA6G,CAAC,CAAA;IACvI,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAA;YACjD,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS;iBACzC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,CAAA;YACb,KAAK,CAAC,IAAI,CACR,kGAAkG,OAAO,YAAY,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,0GAA0G,CACxT,CAAA;QACH,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,oKAAoK,CAAC,CAAA;QAClL,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAA;IAChG,CAAC;SAAM,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CACR,sCAAsC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,oBAAoB,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,kFAAkF,SAAS,8FAA8F,CACzT,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,GAAkB,EAAE,IAAgB;IACpF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,KAAK,CAAA;IACpC,MAAM,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,KAAK,KAAK,CAAA;IAE1D,MAAM,MAAM,GAA4B;QACtC,UAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/B,CAAA;IAED,MAAM,KAAK,GAAgB;QACzB;YACE,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,IAAI;YACd,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAA2B,qBAAqB,EAAE,MAAM,CAAC;SACvE;KACF,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnC,MAAM,QAAQ,GAAG,SAAS,CAA2B,KAAK,EAAE,iBAAiB,CAAC,CAAA;IAC9E,MAAM,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7B,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;IAE1D,IAAI,CAAC,EAAE,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;QAC/B,wEAAwE;QACxE,oEAAoE;QACpE,gBAAgB;QAChB,MAAM,IAAI,KAAK,CACb,+BAA+B,IAAI,CAAC,OAAO,8FAA8F,CAC1I,CAAA;IACH,CAAC;IAED,MAAM,YAAY,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAA;IAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,CAAC,CAAA;IAC7B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;IAE7E,IAAI,gBAAgB,GAAyB,IAAI,CAAA;IACjD,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,IAAI,gBAAgB,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,gBAAgB,GAAG,gBAAgB,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,cAAc,GAAG,IAAI,CAAA;YACrB,gBAAgB,GAAG,IAAI,CAAA;QACzB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAC9B,IAAI,CAAC,OAAO,EACZ,YAAY,EACZ,IAAI,EACJ,OAAO,EAAE,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAC5D,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,cAAc,CACf,CAAA;IAED,OAAO,eAAe,CACpB;QACE,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE;YACZ,MAAM,EAAE,YAAY;YACpB,YAAY,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;YAC1E,WAAW,EAAE,OAAO,EAAE,CAAC,WAAW,KAAK,QAAQ,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YACpG,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;YACvE,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI;SAC7B;QACD,IAAI;QACJ,IAAI,EAAE;YACJ,MAAM,EAAE,UAAU;YAClB,gBAAgB,EAAE,aAAa;SAChC;QACD,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;QACxD,cAAc,EAAE,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QACrE,cAAc,EAAE;YACd,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,OAAO,EAAE,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YACzD,OAAO,EAAE,OAAO,EAAE,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;SAClE;QACD,UAAU,EAAE,gBAAgB;YAC1B,CAAC,CAAC;gBACE,IAAI,EAAE,IAAI,CAAC,OAAO;gBAClB,OAAO,EAAE;oBACP,SAAS,EAAE,gBAAgB,CAAC,SAAS;oBACrC,UAAU,EAAE,gBAAgB,CAAC,UAAU;oBACvC,UAAU,EAAE,gBAAgB,CAAC,UAAU;oBACvC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;iBACpC;gBACD,eAAe,EAAE,gBAAgB,CAAC,eAAe;gBACjD,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;aACpC;YACH,CAAC,CAAC,IAAI;QACR,iBAAiB,EAAE,SAAS;QAC5B,SAAS;QACT,YAAY,EAAE;YACZ,eAAe,EAAE,aAAa,CAAC,KAAK,CAAC;YACrC,QAAQ,EAAE,KAAK,CAAC,OAAO;YACvB,SAAS,EAAE,KAAK,CAAC,QAAQ;YACzB,cAAc,EAAE,MAAM;YACtB,kBAAkB,EAAE,gBAAgB;YACpC,4BAA4B,EAAE,gBAAgB,IAAI,IAAI,KAAK,YAAY;YACvE,yBAAyB,EAAE,cAAc;SAC1C;KACF,EACD,gCAAgC,CACjC,CAAA;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ export declare const DERO_DOC_PRODUCTS: readonly ["derod", "tela", "hologram", "deropay"];
2
+ export type DeroDocProduct = (typeof DERO_DOC_PRODUCTS)[number];
3
+ export declare const DOC_SITE_DIRS: Record<DeroDocProduct, string>;
4
+ export declare const DOC_BASE_URLS: Record<DeroDocProduct, string>;
5
+ export type DeroDocsPage = {
6
+ product: DeroDocProduct;
7
+ slug: string;
8
+ title: string;
9
+ description: string | null;
10
+ canonicalUrl: string;
11
+ sourcePath: string;
12
+ headings: string[];
13
+ plainText: string;
14
+ lastUpdated: string | null;
15
+ };
16
+ export type DocsIndexFile = {
17
+ version: 1;
18
+ generated_at: string;
19
+ page_count: number;
20
+ pages: DeroDocsPage[];
21
+ };
22
+ export declare function normalizeSlug(input: string): string;
23
+ export declare function pathExists(targetPath: string): Promise<boolean>;
24
+ export declare function parseFrontmatter(raw: string): Record<string, string>;
25
+ export declare function stripFrontmatter(raw: string): string;
26
+ export declare function extractHeadings(markdown: string): string[];
27
+ export declare function mdxToPlainText(raw: string): string;
28
+ export declare function indexDocsFromRoot(root: string): Promise<DeroDocsPage[]>;
29
+ export declare function resolveDeroDocsRoot(customRoot?: string): Promise<string | null>;
30
+ //# sourceMappingURL=docs-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-parse.d.ts","sourceRoot":"","sources":["../src/docs-parse.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,mDAAoD,CAAA;AAClF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAKxD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAKxD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,CAAC,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAYD,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWpE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWlD;AAyBD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAqC7E;AAED,wBAAsB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBrF"}