@fenglimg/fabric-cli 1.6.0 → 1.8.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +8 -14
  2. package/dist/{chunk-QSAEGVKE.js → chunk-NMMUETVK.js} +4 -8
  3. package/dist/{chunk-AEOYCVBG.js → chunk-QPCRBQ5Y.js} +52 -5
  4. package/dist/doctor-F52XWWZC.js +98 -0
  5. package/dist/index.js +5 -20
  6. package/dist/{init-LBVOI2QI.js → init-AEO5JU7R.js} +1084 -167
  7. package/dist/{scan-QH76LC7Z.js → scan-NNBNGIZG.js} +2 -4
  8. package/dist/{serve-4J2CQY25.js → serve-466QXQ5Q.js} +17 -9
  9. package/package.json +5 -7
  10. package/templates/agents-md/AGENTS.md.template +7 -7
  11. package/templates/agents-md/variants/cocos.md +7 -7
  12. package/templates/agents-md/variants/next.md +7 -7
  13. package/templates/agents-md/variants/vite.md +7 -7
  14. package/templates/bootstrap/CLAUDE.md +3 -1
  15. package/templates/bootstrap/GEMINI.md +3 -1
  16. package/templates/bootstrap/codex-AGENTS-header.md +3 -1
  17. package/templates/bootstrap/cursor-fabric-bootstrap.mdc +5 -6
  18. package/templates/bootstrap/roo-fabric.md +5 -6
  19. package/templates/bootstrap/windsurf-fabric.md +5 -6
  20. package/templates/claude-skills/fabric-init/SKILL.md +163 -0
  21. package/templates/codex-skills/fabric-init/SKILL.md +153 -18
  22. package/templates/husky/pre-commit +9 -24
  23. package/templates/skill-source/fabric-init/SOURCE.md +157 -0
  24. package/templates/skill-source/fabric-init/clients.json +17 -0
  25. package/dist/approve-YT4DEABS.js +0 -138
  26. package/dist/bootstrap-VGL3AR26.js +0 -16
  27. package/dist/chunk-2YW5CJ32.js +0 -147
  28. package/dist/chunk-6ICJICVU.js +0 -10
  29. package/dist/chunk-BEKSXO5N.js +0 -442
  30. package/dist/chunk-BVTMVW5M.js +0 -159
  31. package/dist/chunk-KOAEIH72.js +0 -270
  32. package/dist/chunk-L43IGJ6X.js +0 -106
  33. package/dist/chunk-T2WJF5I3.js +0 -254
  34. package/dist/chunk-WWNXR34K.js +0 -49
  35. package/dist/chunk-YDZJRLHL.js +0 -155
  36. package/dist/config-EC5L2QNI.js +0 -16
  37. package/dist/doctor-4BPYHV7V.js +0 -134
  38. package/dist/hooks-ZSWVH2JD.js +0 -12
  39. package/dist/human-lint-YSFOZHZ7.js +0 -13
  40. package/dist/ledger-append-3MDNR3GU.js +0 -10
  41. package/dist/pre-commit-53ENJDRZ.js +0 -98
  42. package/dist/sync-meta-IZR2WLIL.js +0 -16
  43. package/dist/update-M5M5PYKE.js +0 -116
  44. package/templates/claude-skills/agents-md-init/SKILL.md +0 -86
  45. package/templates/fabric/human-lock.json +0 -12
@@ -1,24 +1,9 @@
1
- #!/bin/sh
2
- # Fabric pre-commit hook sub-300ms budget via single Node process
3
- # Runs: sync-meta --check-only → human-lint → ledger-append --staged → meta-guard
4
- # Uses local binary (no npx spawn) to avoid 3× Node startup cost.
5
-
6
- FAB_BIN="./node_modules/.bin/fab"
7
-
8
- if [ ! -x "$FAB_BIN" ]; then
9
- echo "fabric: $FAB_BIN not found. Run 'pnpm install' at repo root." >&2
10
- exit 1
11
- fi
12
-
13
- # Single Node invocation covering all three checks + meta guard.
14
- # The `pre-commit` meta-command chains sync-meta/human-lint/ledger-append
15
- # inside one process for minimal startup overhead.
16
- "$FAB_BIN" pre-commit || exit $?
17
-
18
- # Guard: block manual edits to .fabric/agents.meta.json
19
- if git diff --cached --name-only | grep -q '^\.fabric/agents\.meta\.json$'; then
20
- if [ "$FAB_ALLOW_META_EDIT" != '1' ]; then
21
- echo '.fabric/agents.meta.json cannot be manually edited; use fab_update_registry or set FAB_ALLOW_META_EDIT=1' >&2
22
- exit 1
23
- fi
24
- fi
1
+ #!/bin/sh
2
+ # Fabric pre-commit hook: block manual edits to generated metadata.
3
+
4
+ if git diff --cached --name-only | grep -q '^\.fabric/agents\.meta\.json$'; then
5
+ if [ "$FAB_ALLOW_META_EDIT" != '1' ]; then
6
+ echo '.fabric/agents.meta.json cannot be manually edited; update .fabric/rules and run fabric doctor --fix, or set FAB_ALLOW_META_EDIT=1' >&2
7
+ exit 1
8
+ fi
9
+ fi
@@ -0,0 +1,157 @@
1
+ # fabric-init — Canonical Skill Source
2
+
3
+ > This file is the single source of truth for the fabric-init skill.
4
+ > Do NOT edit the per-client SKILL.md files directly.
5
+ > Run `packages/cli/scripts/derive-skills.ts` to regenerate them from this source.
6
+
7
+ ## Precondition
8
+
9
+ MUST: Read `.fabric/forensic.json` before taking any other action. If the file does not
10
+ exist, stop immediately and tell the user: run `fab init` first to generate the evidence
11
+ package.
12
+
13
+ MUST: Check `.fabric/init-context.json`. If it already exists, stop and report that this
14
+ repository appears to have completed initialization already.
15
+
16
+ MUST: Treat `.fabric/bootstrap/README.md` as the authoritative initialization guide for
17
+ the current repository.
18
+
19
+ MUST: Use `.fabric/forensic.json` and repository structure as evidence when deciding what
20
+ to do next.
21
+
22
+ MUST: Preserve protected tokens exactly as written — see the Protected Tokens section.
23
+
24
+ NEVER: Claim initialization is complete without having checked `.fabric/init-context.json`.
25
+
26
+ NEVER: Rewrite or translate protected tokens.
27
+
28
+ NEVER: Ignore `.fabric/bootstrap/README.md` when determining the next initialization step.
29
+
30
+ Treat the following state as initialization pending:
31
+
32
+ - `.fabric/forensic.json` exists
33
+ - `.fabric/init-context.json` does not exist
34
+
35
+ ## Execution Flow — 3 Phases / 3 Rounds
36
+
37
+ ### Phase 1 — Framework Confirmation (1 round, efficient)
38
+
39
+ Display a summary of `framework`, `topology.by_ext`, and `entry_points` from
40
+ `.fabric/forensic.json`. Ask the user 1–2 clarifying questions about the framework
41
+ architecture.
42
+
43
+ Example (Cocos Creator 3.x):
44
+
45
+ > I detected a Cocos Creator 3.8 project. Main scripts are in `assets/scripts` using the
46
+ > `@ccclass + extends Component` pattern. Please confirm: (1) Is this a TypeScript project
47
+ > (not JavaScript)? (2) Are node references injected mainly via `@property(Node)`, or via
48
+ > `find/getChildByName`?
49
+
50
+ Store the user's answers as verified framework assumptions before proceeding to Phase 2.
51
+
52
+ ### Phase 2 — Invariant Extraction (1 round, critical)
53
+
54
+ Based on the `recommendations_for_skill` list in `.fabric/forensic.json`, ask the user
55
+ 3–5 invariant questions covering three categories:
56
+
57
+ - `ban`: things that must never appear — e.g. `any`, `async` in `update()`, find-by-name
58
+ - `require`: things that must always be present — e.g. strict TypeScript, `@ccclass`
59
+ decorator, imports only from `cc`
60
+ - `protect`: directories or files that AI must not modify — typically
61
+ `assets/prefabs/**`, `assets/scenes/**`, `**/*.meta`
62
+
63
+ Principles:
64
+
65
+ - Ask only about invariants, not about preferences.
66
+ - Each question accepts only yes / no / a concrete rule — never accept vague answers.
67
+ - Do not auto-infer hard constraints the user has not confirmed.
68
+
69
+ ### Phase 3 — Construction and Landing (1 round, automated)
70
+
71
+ #### 3.1 Write `.fabric/init-context.json`
72
+
73
+ Fields required:
74
+
75
+ - `framework`
76
+ - `architecture_patterns`
77
+ - `invariants`
78
+ - `domain_groups`
79
+ - `interview_trail`
80
+ - `forensic_ref`
81
+
82
+ Writing rules:
83
+
84
+ - `invariants[].type` MUST be one of `ban`, `require`, `protect`.
85
+ - `domain_groups` is inferred from `entry_points` and interview results.
86
+ - `interview_trail[]` MUST record the raw Q&A from Phase 1 and Phase 2.
87
+ - `forensic_ref` MUST be `.fabric/forensic.json`.
88
+
89
+ #### 3.2 Generate layered `AGENTS.md`
90
+
91
+ Root `AGENTS.md` requirements:
92
+
93
+ - MUST be within 300 lines.
94
+ - Structure:
95
+ - `# {projectName} — L0 AGENTS.md`
96
+ - `<!-- fab:index -->`: populated with the `domain_groups` index
97
+ - `## L0 AI Constraints`: derived from invariants, grouped by `ban`, `require`, `protect`
98
+ - `## @HUMAN`: protect paths and any human-declared protection rules
99
+ - `## L1 Candidate Notes`: candidate sub-module descriptions for each domain group
100
+
101
+ If `domain_groups.length >= 2`, generate a `{group_path}/AGENTS.md` for each group.
102
+ Maximum depth is L3; total nesting MUST NOT exceed 4 levels.
103
+
104
+ #### 3.3 Update `.fabric/agents.meta.json`
105
+
106
+ - The `nodes` tree MUST match the generated AGENTS hierarchy.
107
+ - Update the hash of every AGENTS.md file that was written.
108
+ - Maintain a consistent internal revision hash chain.
109
+
110
+ #### 3.4 Final output
111
+
112
+ List all generated files for the user and recommend running `fabric doctor --fix` for
113
+ ongoing maintenance.
114
+
115
+ ## Hard Rules
116
+
117
+ - Zero TODO: never generate `TODO`, `TBD`, placeholders, or stubs in output files.
118
+ - No YAML frontmatter in outputs: generated `AGENTS.md` files MUST NOT contain YAML
119
+ frontmatter.
120
+ - Root `AGENTS.md` MUST be <= 300 lines.
121
+ - Total AGENTS nesting MUST be <= 4 levels.
122
+ - Do not auto-infer invariants the user has not confirmed.
123
+ - When content is uncertain, omit it — do not leave placeholders.
124
+
125
+ ## Output Contract
126
+
127
+ On successful completion the following files exist or are updated:
128
+
129
+ | File | Action |
130
+ |------|--------|
131
+ | `.fabric/init-context.json` | Created with all required fields |
132
+ | `AGENTS.md` | Created (root L0) |
133
+ | `{group_path}/AGENTS.md` | Created for each domain group (when applicable) |
134
+ | `.fabric/agents.meta.json` | Updated nodes tree + hashes |
135
+
136
+ On failure or early termination the skill MUST leave no partial files. If a write fails
137
+ mid-sequence, report the failure and the exact file that was not written.
138
+
139
+ ## Protected Tokens
140
+
141
+ The following tokens MUST be preserved exactly as shown — same casing, same punctuation,
142
+ never translated:
143
+
144
+ | Token | Type |
145
+ |-------|------|
146
+ | `AGENTS.md` | Filename |
147
+ | `FABRIC.md` | Filename |
148
+ | `.fabric/agents.meta.json` | Path |
149
+ | `.fabric/init-context.json` | Path |
150
+ | `.fabric/forensic.json` | Path |
151
+ | `.fabric/bootstrap/README.md` | Path |
152
+ | `MUST` | Keyword |
153
+ | `NEVER` | Keyword |
154
+ | `fab init` | CLI command |
155
+ | `fabric doctor --fix` | CLI command |
156
+ | `<!-- fab:index -->` | HTML comment marker |
157
+ | `@HUMAN` | Section marker |
@@ -0,0 +1,17 @@
1
+ {
2
+ "claude": {
3
+ "outputName": "fabric-init",
4
+ "frontmatter": {
5
+ "name": "fabric-init",
6
+ "description": "Use this skill when fab init just completed, when forensic.json was generated, or when the user is asking to initialize AGENTS.md. This skill runs a 3-phase initialization interview, writes .fabric/init-context.json, generates layered AGENTS.md, and updates .fabric/agents.meta.json.",
7
+ "allowed-tools": ["Read", "Write", "Glob", "Grep", "Bash"]
8
+ }
9
+ },
10
+ "codex": {
11
+ "outputName": "fabric-init",
12
+ "frontmatter": {
13
+ "name": "fabric-init",
14
+ "description": "Use this skill when .fabric/forensic.json exists and this repository still needs the remaining Fabric initialization steps."
15
+ }
16
+ }
17
+ }
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- padEnd
4
- } from "./chunk-WWNXR34K.js";
5
- import {
6
- t
7
- } from "./chunk-6ICJICVU.js";
8
-
9
- // src/commands/approve.ts
10
- import { createInterface } from "readline/promises";
11
- import { stdin as input, stdout as output } from "process";
12
- import { isAbsolute, resolve } from "path";
13
- import { approveHumanLock, readHumanLock } from "@fenglimg/fabric-server";
14
- import { defineCommand, renderUsage } from "citty";
15
- var approveCommand = defineCommand({
16
- meta: {
17
- name: "approve",
18
- description: t("cli.approve.description")
19
- },
20
- args: {
21
- all: {
22
- type: "boolean",
23
- description: t("cli.approve.args.all.description"),
24
- default: false
25
- },
26
- interactive: {
27
- type: "boolean",
28
- description: t("cli.approve.args.interactive.description"),
29
- default: false
30
- },
31
- target: {
32
- type: "string",
33
- description: t("cli.approve.args.target.description"),
34
- default: process.cwd()
35
- }
36
- },
37
- async run({ args }) {
38
- const target = normalizeTarget(args.target);
39
- if (args.all === args.interactive) {
40
- writeStdout(await renderUsage(approveCommand));
41
- process.exitCode = 1;
42
- return;
43
- }
44
- if (args.all) {
45
- await runApproveAll(target);
46
- return;
47
- }
48
- await runApproveInteractive(target);
49
- }
50
- });
51
- var approve_default = approveCommand;
52
- async function runApproveAll(projectRoot) {
53
- const driftEntries = await readDriftEntries(projectRoot);
54
- if (driftEntries.length === 0) {
55
- writeStdout(t("cli.approve.no-drift"));
56
- return;
57
- }
58
- let approvedCount = 0;
59
- for (const entry of driftEntries) {
60
- await approveEntry(projectRoot, entry);
61
- approvedCount += 1;
62
- }
63
- writeStdout(t("cli.approve.summary", { approved: String(approvedCount), skipped: "0", total: String(driftEntries.length) }));
64
- }
65
- async function runApproveInteractive(projectRoot) {
66
- const driftEntries = await readDriftEntries(projectRoot);
67
- if (driftEntries.length === 0) {
68
- writeStdout(t("cli.approve.no-drift"));
69
- return;
70
- }
71
- const rl = createInterface({ input, output });
72
- let approvedCount = 0;
73
- let skippedCount = 0;
74
- try {
75
- for (const entry of driftEntries) {
76
- writeStdout(formatEntry(entry));
77
- const answer = (await rl.question(t("cli.approve.prompt"))).trim().toLowerCase();
78
- if (answer === "y" || answer === "yes") {
79
- await approveEntry(projectRoot, entry);
80
- approvedCount += 1;
81
- writeStdout(t("cli.approve.approved-one", { location: formatLocation(entry) }));
82
- continue;
83
- }
84
- skippedCount += 1;
85
- writeStdout(t("cli.approve.skipped-one", { location: formatLocation(entry) }));
86
- }
87
- } finally {
88
- rl.close();
89
- }
90
- writeStdout(
91
- t("cli.approve.summary", {
92
- approved: String(approvedCount),
93
- skipped: String(skippedCount),
94
- total: String(driftEntries.length)
95
- })
96
- );
97
- }
98
- async function readDriftEntries(projectRoot) {
99
- const entries = await readHumanLock(projectRoot);
100
- return entries.filter((entry) => entry.drift);
101
- }
102
- async function approveEntry(projectRoot, entry) {
103
- await approveHumanLock(projectRoot, {
104
- file: entry.file,
105
- start_line: entry.start_line,
106
- end_line: entry.end_line,
107
- new_hash: entry.current_hash
108
- });
109
- }
110
- function normalizeTarget(targetInput) {
111
- return isAbsolute(targetInput) ? targetInput : resolve(process.cwd(), targetInput);
112
- }
113
- function formatEntry(entry) {
114
- return [
115
- formatLocation(entry),
116
- `${padEnd(t("cli.approve.table.expected"), 10)} ${shortenHash(entry.hash)}`,
117
- `${padEnd(t("cli.approve.table.current"), 10)} ${shortenHash(entry.current_hash)}`
118
- ].join("\n");
119
- }
120
- function formatLocation(entry) {
121
- return `${entry.file}:${entry.start_line}-${entry.end_line}`;
122
- }
123
- function shortenHash(value) {
124
- if (value === "missing") {
125
- return t("cli.shared.missing");
126
- }
127
- return value.slice(0, 15);
128
- }
129
- function writeStdout(message) {
130
- process.stdout.write(`${message}
131
- `);
132
- }
133
- export {
134
- approveCommand,
135
- approve_default as default,
136
- runApproveAll,
137
- runApproveInteractive
138
- };
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- bootstrapCommand,
4
- bootstrap_default,
5
- installBootstrap
6
- } from "./chunk-T2WJF5I3.js";
7
- import "./chunk-QSAEGVKE.js";
8
- import "./chunk-AEOYCVBG.js";
9
- import "./chunk-WWNXR34K.js";
10
- import "./chunk-BEKSXO5N.js";
11
- import "./chunk-6ICJICVU.js";
12
- export {
13
- bootstrapCommand,
14
- bootstrap_default as default,
15
- installBootstrap
16
- };
@@ -1,147 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- t
4
- } from "./chunk-6ICJICVU.js";
5
-
6
- // src/commands/ledger-append.ts
7
- import { execSync } from "child_process";
8
- import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
9
- import { basename, isAbsolute, resolve } from "path";
10
- import { getLedgerPath, getLegacyLedgerPath, LEGACY_LEDGER_PATH, LEDGER_PATH } from "@fenglimg/fabric-server";
11
- import { defineCommand } from "citty";
12
- var INITIAL_PARENT_SHA = "root";
13
- var ledgerAppendCommand = defineCommand({
14
- meta: {
15
- name: "ledger-append",
16
- description: t("cli.ledger-append.description")
17
- },
18
- args: {
19
- target: {
20
- type: "string",
21
- description: t("cli.ledger-append.args.target.description"),
22
- default: process.cwd()
23
- },
24
- staged: {
25
- type: "boolean",
26
- description: t("cli.ledger-append.args.staged.description"),
27
- default: false
28
- }
29
- },
30
- async run({ args }) {
31
- const target = normalizeTarget(args.target);
32
- assertExistingDirectory(target);
33
- if (!args.staged) {
34
- writeStderr(t("cli.ledger-append.requires-staged"));
35
- process.exitCode = 1;
36
- return;
37
- }
38
- const stagedFiles = getStagedFiles(target).filter((file) => file !== LEGACY_LEDGER_PATH && file !== LEDGER_PATH);
39
- if (stagedFiles.length === 0) {
40
- return;
41
- }
42
- const intent = deriveIntent(stagedFiles);
43
- const diffStat = readDiffStat(target).trim();
44
- const entry = {
45
- ts: Date.now(),
46
- source: "human",
47
- parent_sha: readParentSha(target),
48
- intent,
49
- affected_paths: stagedFiles,
50
- diff_stat: diffStat
51
- };
52
- if (hasMatchingTailEntry(target, entry)) {
53
- return;
54
- }
55
- const ledgerPath = getLedgerPath(target);
56
- mkdirSync(resolve(target, ".fabric"), { recursive: true });
57
- appendFileSync(ledgerPath, `${JSON.stringify(entry)}
58
- `, "utf8");
59
- execGit(target, `git add ${LEDGER_PATH}`);
60
- }
61
- });
62
- var ledger_append_default = ledgerAppendCommand;
63
- function normalizeTarget(targetInput) {
64
- return isAbsolute(targetInput) ? targetInput : resolve(process.cwd(), targetInput);
65
- }
66
- function assertExistingDirectory(target) {
67
- if (!existsSync(target) || !statSync(target).isDirectory()) {
68
- throw new Error(t("cli.shared.target-invalid", { target }));
69
- }
70
- }
71
- function getStagedFiles(target) {
72
- const output = execGit(target, "git diff --cached --name-only --no-renames");
73
- return output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
74
- }
75
- function readDiffStat(target) {
76
- return execGit(target, "git diff --cached --stat");
77
- }
78
- function readParentSha(target) {
79
- try {
80
- return execGit(target, "git rev-parse --short HEAD").trim();
81
- } catch {
82
- return INITIAL_PARENT_SHA;
83
- }
84
- }
85
- function deriveIntent(stagedFiles) {
86
- const explicitIntent = process.env.FABRIC_INTENT?.trim();
87
- if (explicitIntent) {
88
- return explicitIntent;
89
- }
90
- const uniqueNames = Array.from(new Set(stagedFiles.map((file) => basename(file))));
91
- const head = uniqueNames.slice(0, 2).join(", ");
92
- const suffix = uniqueNames.length > 2 ? t("cli.ledger-append.intent.auto-more", { count: String(uniqueNames.length - 2) }) : "";
93
- return t("cli.ledger-append.intent.auto", { head, suffix });
94
- }
95
- function hasMatchingTailEntry(target, entry) {
96
- const ledgerPath = resolveTailLedgerPath(target);
97
- if (!existsSync(ledgerPath)) {
98
- return false;
99
- }
100
- const tail = readFileSync(ledgerPath, "utf8").trim().split(/\r?\n/).filter(Boolean).reverse().find((line) => isLedgerEntryLine(line));
101
- if (!tail) {
102
- return false;
103
- }
104
- try {
105
- const parsed = JSON.parse(tail);
106
- return parsed.parent_sha === entry.parent_sha && parsed.intent === entry.intent && Array.isArray(parsed.affected_paths) && parsed.affected_paths.length === entry.affected_paths.length && parsed.affected_paths.every((value, index) => value === entry.affected_paths[index]) && normalizeDiffStat(parsed.diff_stat) === normalizeDiffStat(entry.diff_stat);
107
- } catch {
108
- return false;
109
- }
110
- }
111
- function resolveTailLedgerPath(target) {
112
- const canonicalPath = getLedgerPath(target);
113
- if (existsSync(canonicalPath)) {
114
- return canonicalPath;
115
- }
116
- return getLegacyLedgerPath(target);
117
- }
118
- function isLedgerEntryLine(line) {
119
- try {
120
- const parsed = JSON.parse(line);
121
- return parsed.kind !== "mcp-event";
122
- } catch {
123
- return false;
124
- }
125
- }
126
- function normalizeDiffStat(diffStat) {
127
- if (typeof diffStat !== "string") {
128
- return "";
129
- }
130
- return diffStat.split(/\r?\n/).map((line) => line.trim()).map((line) => line.replace(/\s+\|\s+/g, " | ")).map((line) => line.replace(/\s+/g, " ")).filter((line) => line.length > 0).filter((line) => !line.includes(LEGACY_LEDGER_PATH)).filter((line) => !line.includes(LEDGER_PATH)).filter((line) => !/\d+ files? changed(?:, \d+ insertions?\(\+\))?(?:, \d+ deletions?\(-\))?$/.test(line.trim())).join("\n");
131
- }
132
- function execGit(target, command) {
133
- return execSync(command, {
134
- cwd: target,
135
- encoding: "utf8",
136
- stdio: ["ignore", "pipe", "pipe"]
137
- });
138
- }
139
- function writeStderr(message) {
140
- process.stderr.write(`${message}
141
- `);
142
- }
143
-
144
- export {
145
- ledgerAppendCommand,
146
- ledger_append_default
147
- };
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/i18n.ts
4
- import { createTranslator, detectNodeLocale } from "@fenglimg/fabric-shared";
5
- var locale = detectNodeLocale();
6
- var t = createTranslator(locale);
7
-
8
- export {
9
- t
10
- };