@nac3/forge-cli 1.9.2 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/doctrine_digest.d.ts.map +1 -1
- package/dist/chat/doctrine_digest.js +15 -0
- package/dist/chat/doctrine_digest.js.map +1 -1
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +13363 -12980
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +86 -10
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/sizing_section.d.ts +9 -0
- package/dist/chat/sizing_section.d.ts.map +1 -0
- package/dist/chat/sizing_section.js +73 -0
- package/dist/chat/sizing_section.js.map +1 -0
- package/dist/chat/tools/app_backend_dispatch.d.ts.map +1 -1
- package/dist/chat/tools/app_backend_dispatch.js +46 -0
- package/dist/chat/tools/app_backend_dispatch.js.map +1 -1
- package/dist/chat/tools/config_write.d.ts +2 -3
- package/dist/chat/tools/config_write.d.ts.map +1 -1
- package/dist/chat/tools/config_write.js +3 -13
- package/dist/chat/tools/config_write.js.map +1 -1
- package/dist/chat/tools/pending.d.ts +8 -0
- package/dist/chat/tools/pending.d.ts.map +1 -1
- package/dist/chat/tools/pending.js +26 -0
- package/dist/chat/tools/pending.js.map +1 -1
- package/dist/chat/tools/shell.d.ts +5 -0
- package/dist/chat/tools/shell.d.ts.map +1 -1
- package/dist/chat/tools/shell.js +60 -0
- package/dist/chat/tools/shell.js.map +1 -1
- package/dist/chat/tools/sizing.d.ts +66 -0
- package/dist/chat/tools/sizing.d.ts.map +1 -0
- package/dist/chat/tools/sizing.js +171 -0
- package/dist/chat/tools/sizing.js.map +1 -0
- package/dist/chat/tools.d.ts.map +1 -1
- package/dist/chat/tools.js +25 -2
- package/dist/chat/tools.js.map +1 -1
- package/dist/commands/clarify.d.ts.map +1 -1
- package/dist/commands/clarify.js +163 -1
- package/dist/commands/clarify.js.map +1 -1
- package/dist/commands/pending.d.ts.map +1 -1
- package/dist/commands/pending.js +9 -0
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/triage.d.ts +61 -7
- package/dist/commands/triage.d.ts.map +1 -1
- package/dist/commands/triage.js +106 -13
- package/dist/commands/triage.js.map +1 -1
- package/dist/core/forge_profile.d.ts +11 -1
- package/dist/core/forge_profile.d.ts.map +1 -1
- package/dist/core/forge_profile.js +39 -1
- package/dist/core/forge_profile.js.map +1 -1
- package/dist/core/operate_guard.d.ts +3 -0
- package/dist/core/operate_guard.d.ts.map +1 -1
- package/dist/core/operate_guard.js +13 -0
- package/dist/core/operate_guard.js.map +1 -1
- package/dist/docs/doctrine/gates.md +33 -21
- package/dist/docs/doctrine/sizing.md +182 -0
- package/dist/nac3/backend_tools.d.ts +14 -0
- package/dist/nac3/backend_tools.d.ts.map +1 -1
- package/dist/nac3/backend_tools.js +31 -1
- package/dist/nac3/backend_tools.js.map +1 -1
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +172 -5
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/pending/commit_files.d.ts +3 -0
- package/dist/pending/commit_files.d.ts.map +1 -0
- package/dist/pending/commit_files.js +42 -0
- package/dist/pending/commit_files.js.map +1 -0
- package/dist/pending/store.d.ts +12 -0
- package/dist/pending/store.d.ts.map +1 -1
- package/dist/pending/store.js +66 -0
- package/dist/pending/store.js.map +1 -1
- package/dist/pending/types.d.ts +50 -0
- package/dist/pending/types.d.ts.map +1 -1
- package/dist/pending/types.js.map +1 -1
- package/dist/sizing/model.d.ts +200 -0
- package/dist/sizing/model.d.ts.map +1 -0
- package/dist/sizing/model.js +423 -0
- package/dist/sizing/model.js.map +1 -0
- package/dist/sizing/store.d.ts +114 -0
- package/dist/sizing/store.d.ts.map +1 -0
- package/dist/sizing/store.js +235 -0
- package/dist/sizing/store.js.map +1 -0
- package/dist/tasks/supervisor.d.ts +21 -0
- package/dist/tasks/supervisor.d.ts.map +1 -1
- package/dist/tasks/supervisor.js +39 -3
- package/dist/tasks/supervisor.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workflow/definitions.js +1 -1
- package/dist/workflow/definitions.js.map +1 -1
- package/dist/workflow/state.d.ts +28 -0
- package/dist/workflow/state.d.ts.map +1 -1
- package/dist/workflow/state.js.map +1 -1
- package/docs/doctrine/gates.md +33 -21
- package/docs/doctrine/sizing.md +182 -0
- package/package.json +117 -117
- package/src/i18n/catalogs/ar.json +1 -0
- package/src/i18n/catalogs/de.json +1 -0
- package/src/i18n/catalogs/en.json +1 -0
- package/src/i18n/catalogs/es.json +1 -0
- package/src/i18n/catalogs/fr.json +1 -0
- package/src/i18n/catalogs/hi.json +1 -0
- package/src/i18n/catalogs/it.json +1 -0
- package/src/i18n/catalogs/ja.json +1 -0
- package/src/i18n/catalogs/pt.json +1 -0
- package/src/i18n/catalogs/zh.json +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Sizing doctrine -- fixed options, measured envelopes
|
|
2
|
+
|
|
3
|
+
This doctrine exists because the previous one was not enough.
|
|
4
|
+
|
|
5
|
+
`concurrency-scale.md` opens with *"Every application Forge designs MUST
|
|
6
|
+
be sized to its expected concurrency from day one. Scale is a
|
|
7
|
+
RELEVAMIENTO input, not an afterthought bolted on when the app falls
|
|
8
|
+
over."* That was already written when ADIP-KIKAN was built with its
|
|
9
|
+
entire working set resident in the Node heap, at a volumetry
|
|
10
|
+
(5.000 affiliates x 40 campaigns/year -> ~3,4M rows/year -> ~8 GB of
|
|
11
|
+
live heap per year against a 2-4 GB V8 ceiling) that hits a wall in
|
|
12
|
+
months.
|
|
13
|
+
|
|
14
|
+
So the lesson is not "write more doctrine". The lesson is that **prose is
|
|
15
|
+
advisory**. This doctrine describes a mechanism; the mechanism is the
|
|
16
|
+
code in `src/sizing/`.
|
|
17
|
+
|
|
18
|
+
## The four holes the Kikan post mortem found
|
|
19
|
+
|
|
20
|
+
1. **The wrong axis.** The only volumetry Forge asked for was PEAK
|
|
21
|
+
CONCURRENCY (`src/commands/triage.ts`), and only to pick a complexity
|
|
22
|
+
tier. Kikan has 100 concurrent users -- a low number -- and died of
|
|
23
|
+
ROW COUNT. Data volume x retention was never a question.
|
|
24
|
+
2. **No hardware envelope.** None. No RAM, no runtime heap ceiling, no
|
|
25
|
+
disk. The architecture was chosen without knowing the machine -- and
|
|
26
|
+
the ceiling that actually kills a Node process is V8's
|
|
27
|
+
`heap_size_limit`, a property of the machine and runtime, not of the
|
|
28
|
+
business.
|
|
29
|
+
3. **A free-form choice.** Forge invented an approach and wrote a
|
|
30
|
+
rationale. With no fixed option set carrying validity ranges, there
|
|
31
|
+
was nothing to violate.
|
|
32
|
+
4. **A soft gate.** The only gate touching volumetry was `GS4`, and soft
|
|
33
|
+
gates do not block.
|
|
34
|
+
|
|
35
|
+
And the deepest one, which is really a fifth: **in Kikan the decision was
|
|
36
|
+
never taken.** There was no moment called "choose the persistence
|
|
37
|
+
architecture". The engine was written against a synchronous in-memory
|
|
38
|
+
store as a prototype, durability was bolted on later, and the choice was
|
|
39
|
+
made by omission in the commit that decided not to rewrite the engine. A
|
|
40
|
+
gate that only fires in the design phase would have missed it.
|
|
41
|
+
|
|
42
|
+
## What you must do
|
|
43
|
+
|
|
44
|
+
### 1. Ask for five things, never four
|
|
45
|
+
|
|
46
|
+
During relevamiento -- and before any change that makes a load-bearing
|
|
47
|
+
decision about state:
|
|
48
|
+
|
|
49
|
+
- **Entities and their cardinality.** "5.000 affiliates", "20.000
|
|
50
|
+
customers".
|
|
51
|
+
- **Event rate per entity per year.** "40 campaigns per affiliate per
|
|
52
|
+
year".
|
|
53
|
+
- **Rows per event, across EVERY table the event writes.** This is the
|
|
54
|
+
number people get wrong. In Kikan one campaign-affiliate event leaves
|
|
55
|
+
about 17 rows: a pending, three or four dispatch items, five messages,
|
|
56
|
+
as many traces, plus run events and a conversation. Not one row.
|
|
57
|
+
- **Retention per data CLASS.** Business data and trace data have
|
|
58
|
+
different retention rights, and this is the distinction Kikan never
|
|
59
|
+
made. `0 days` means forever, and forever means unbounded.
|
|
60
|
+
- **The hardware envelope**: `ram_mb`, `heap_cap_mb`, `disk_gb`,
|
|
61
|
+
`vcpus`. `heap_cap_mb` is the RUNTIME heap ceiling
|
|
62
|
+
(`node -e "console.log(require('v8').getHeapStatistics().heap_size_limit)"`),
|
|
63
|
+
**not** the RAM of the machine. Using RAM here is exactly what makes an
|
|
64
|
+
in-memory design look survivable.
|
|
65
|
+
|
|
66
|
+
`yf triage` asks the first three (and uses the row rate to pick the tier);
|
|
67
|
+
`yf clarify quantitative` asks the rest, derives, and records. In a chat
|
|
68
|
+
session, ask them yourself and call `yujin.sizing.record`.
|
|
69
|
+
|
|
70
|
+
Ask the owner. Do not invent the numbers. If the owner does not know,
|
|
71
|
+
propose a default, say out loud that it is a default, and record it --
|
|
72
|
+
the record keeps every revision, so a wrong assumption is findable
|
|
73
|
+
later instead of invisible.
|
|
74
|
+
|
|
75
|
+
### 2. Let the numbers be derived, not argued
|
|
76
|
+
|
|
77
|
+
`yujin.sizing.show` derives, from those inputs: rows/year, rows at the
|
|
78
|
+
horizon, live rows after retention, the heap a resident set would take
|
|
79
|
+
and what share of the ceiling that is, and disk at the horizon. You do
|
|
80
|
+
not estimate these and you do not debate them.
|
|
81
|
+
|
|
82
|
+
### 3. Pick one option per axis, from the fixed catalogue
|
|
83
|
+
|
|
84
|
+
Four axes. The option ids and their envelopes live in
|
|
85
|
+
`src/sizing/model.ts`; `yujin.sizing.show` prints the catalogue and
|
|
86
|
+
which options the current volumetry admits.
|
|
87
|
+
|
|
88
|
+
**`state_residency` -- where the working set lives**
|
|
89
|
+
|
|
90
|
+
| Option | Admissible when |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `memory-only` | Zero users. A prototype nobody depends on |
|
|
93
|
+
| `memory-write-through` | Every data class bounded by retention AND the live set under 25% of the heap ceiling |
|
|
94
|
+
| `sql-async` | Always. The default |
|
|
95
|
+
| `sql-plus-narrow-cache` | Only with a `measured_hotspot` naming the measurement that justifies it |
|
|
96
|
+
|
|
97
|
+
25% and not 80%: the heap also holds every request in flight, the
|
|
98
|
+
declarative catalog and V8's own slack, and mark-compact pauses grow with
|
|
99
|
+
the live set long before the ceiling is reached. The system becomes
|
|
100
|
+
unusable before it crashes.
|
|
101
|
+
|
|
102
|
+
**`pagination` -- how a page is produced**
|
|
103
|
+
|
|
104
|
+
| Option | Admissible when |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `in-memory-slice` | Nothing unbounded AND under 100.000 rows at the horizon |
|
|
107
|
+
| `sql-limit-offset` | Always |
|
|
108
|
+
| `sql-keyset` | Always; the right default past a few hundred thousand rows |
|
|
109
|
+
|
|
110
|
+
A slice taken after materialising the collection protects the wire, not
|
|
111
|
+
the server. Kikan's own `paginacion.js` says so in a comment and does it
|
|
112
|
+
anyway.
|
|
113
|
+
|
|
114
|
+
**`retention` -- what bounds each class**
|
|
115
|
+
|
|
116
|
+
| Option | Admissible when |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `retention-none` | Not with a resident working set, and only while projected disk stays under 25% |
|
|
119
|
+
| `retention-by-age` | At least one class declares a window |
|
|
120
|
+
| `retention-by-age-and-count` | Same as above (it is a superset); the row cap is what survives a spike |
|
|
121
|
+
|
|
122
|
+
A retention mechanism that ships inert (`max_days: 0`) is not retention.
|
|
123
|
+
Kikan shipped one and it deleted nothing for a year.
|
|
124
|
+
|
|
125
|
+
Consequence, and it is deliberate: with retention `0/0` the retention axis
|
|
126
|
+
has **no admissible option at all**, so a project cannot be sized until it
|
|
127
|
+
declares what bounds each data class. That is the Kikan lesson in one line.
|
|
128
|
+
|
|
129
|
+
**`write_concurrency` -- what makes a multi-step mutation atomic**
|
|
130
|
+
|
|
131
|
+
| Option | Admissible when |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `implicit-single-thread` | Only with a synchronous resident store AND at most one concurrent user |
|
|
134
|
+
| `explicit-transactions` | Always |
|
|
135
|
+
| `unique-keys-and-upsert` | Always; the only correct fix for a check-then-act race |
|
|
136
|
+
|
|
137
|
+
The moment reads become asynchronous, every `findOne`-then-`insert`
|
|
138
|
+
becomes a race, and the guarantee that used to be free disappears
|
|
139
|
+
without anything in the code changing shape. Kikan has 27 of those
|
|
140
|
+
patterns and zero transactions.
|
|
141
|
+
|
|
142
|
+
### 4. Record it, and accept the refusal
|
|
143
|
+
|
|
144
|
+
`yujin.sizing.record` persists the sizing **only if every choice is
|
|
145
|
+
inside its envelope**. A choice outside is refused and nothing is
|
|
146
|
+
written. The refusal carries the derived numbers, which axes failed, and
|
|
147
|
+
what would be admissible -- so fixing it is one more call, not a
|
|
148
|
+
negotiation.
|
|
149
|
+
|
|
150
|
+
The record is not a permit. `sizingGate()` re-validates it on every read,
|
|
151
|
+
so a sizing that was fine at 500 affiliates stops passing when the
|
|
152
|
+
declared number becomes 50.000.
|
|
153
|
+
|
|
154
|
+
### 5. Re-check against reality
|
|
155
|
+
|
|
156
|
+
`yujin.sizing.check` takes real counts (a `COUNT(*)` per table, an infra
|
|
157
|
+
report) and re-runs the envelopes with the observed rate substituted in.
|
|
158
|
+
The answer is not "the estimate was 3x off"; it is "at the rate you
|
|
159
|
+
actually have, the architecture you chose is no longer admissible". Run
|
|
160
|
+
it whenever real numbers exist. This is what catches a bad sizing in
|
|
161
|
+
month 2 instead of month 12.
|
|
162
|
+
|
|
163
|
+
### 6. The prototype trigger
|
|
164
|
+
|
|
165
|
+
When a surface stops being a prototype -- a test store becomes the
|
|
166
|
+
production store, an in-memory thing gets durability bolted on, a demo
|
|
167
|
+
starts holding real data -- set `load_bearing_since`. From then on the
|
|
168
|
+
gate applies outside any workflow.
|
|
169
|
+
|
|
170
|
+
This is the Kikan case, and it is the one a design-phase gate alone
|
|
171
|
+
cannot catch.
|
|
172
|
+
|
|
173
|
+
## Proportionality
|
|
174
|
+
|
|
175
|
+
None of this is a licence to gold-plate. A twenty-user internal tool with
|
|
176
|
+
two tables sizes in one call and picks `sql-async` +
|
|
177
|
+
`sql-limit-offset` + `retention-by-age` + `explicit-transactions`, which
|
|
178
|
+
is the recommendation anyway. The cost of the gate for a small system is
|
|
179
|
+
one verb call; the cost of not having it was ADIP-KIKAN.
|
|
180
|
+
|
|
181
|
+
What the gate forbids is not ambition. It is choosing an architecture
|
|
182
|
+
without knowing the numbers, and then discovering them in production.
|
package/package.json
CHANGED
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@nac3/forge-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
|
|
5
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
-
"author": "Pablo Kuschnirof <pablo@rpaforce.com>",
|
|
7
|
-
"homepage": "https://github.com/yujinapp/yujin-forge#readme",
|
|
8
|
-
"bugs": {
|
|
9
|
-
"url": "https://github.com/yujinapp/yujin-forge/issues"
|
|
10
|
-
},
|
|
11
|
-
"bin": {
|
|
12
|
-
"yf": "./dist/bin/yf.js"
|
|
13
|
-
},
|
|
14
|
-
"type": "module",
|
|
15
|
-
"exports": {
|
|
16
|
-
".": "./dist/index.js"
|
|
17
|
-
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"version": "node scripts/sync_version.mjs && git add src/version.ts",
|
|
20
|
-
"build": "tsc && node scripts/copy_qa_assets.mjs",
|
|
21
|
-
"dev": "tsx watch src/bin/yf.ts",
|
|
22
|
-
"typecheck": "tsc --noEmit",
|
|
23
|
-
"typecheck:all": "pnpm typecheck && pnpm --filter @yujin/hito4-server typecheck && pnpm --filter @yujin/forge-mobile typecheck",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"test:watch": "vitest",
|
|
26
|
-
"lint": "tsc --noEmit",
|
|
27
|
-
"yf": "tsx src/bin/yf.ts",
|
|
28
|
-
"catalog:lint": "node scripts/catalog_lint.mjs",
|
|
29
|
-
"pairing:check": "node scripts/check_pairing_sync.mjs",
|
|
30
|
-
"brain-matrix:gate": "node scripts/brain_matrix_gate.mjs",
|
|
31
|
-
"hito4:lint": "node scripts/hito4_lint_bundle.mjs",
|
|
32
|
-
"publish-alpha-emergency": "node scripts/publish_alpha_emergency.mjs",
|
|
33
|
-
"prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run catalog:lint && pnpm run test && pnpm run brain-matrix:gate && pnpm run hito4:lint"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@anthropic-ai/sdk": "^0.32.1",
|
|
37
|
-
"@aws-sdk/client-ecs": "^3.1053.0",
|
|
38
|
-
"@noble/ciphers": "^2.2.0",
|
|
39
|
-
"@noble/hashes": "^2.2.0",
|
|
40
|
-
"@scure/base": "^2.2.0",
|
|
41
|
-
"better-sqlite3": "^12.10.0",
|
|
42
|
-
"commander": "12.1.0",
|
|
43
|
-
"cross-spawn": "^7.0.6",
|
|
44
|
-
"dotenv": "^17.4.2",
|
|
45
|
-
"kleur": "4.1.5",
|
|
46
|
-
"mammoth": "^1.8.0",
|
|
47
|
-
"node-html-parser": "6.1.13",
|
|
48
|
-
"pdfjs-dist": "^4.10.38",
|
|
49
|
-
"prompts": "2.4.2",
|
|
50
|
-
"qrcode": "^1.5.4",
|
|
51
|
-
"typescript": "5.7.2",
|
|
52
|
-
"xlsx": "npm:@e965/xlsx@0.20.3"
|
|
53
|
-
},
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@playwright/test": "^1.60.0",
|
|
56
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
57
|
-
"@types/cross-spawn": "^6.0.6",
|
|
58
|
-
"@types/node": "22.10.2",
|
|
59
|
-
"@types/prompts": "2.4.9",
|
|
60
|
-
"@types/qrcode": "^1.5.6",
|
|
61
|
-
"acorn": "^8.16.0",
|
|
62
|
-
"pixelmatch": "^7.2.0",
|
|
63
|
-
"pngjs": "^7.0.0",
|
|
64
|
-
"tsx": "4.19.2",
|
|
65
|
-
"vitest": "2.1.8"
|
|
66
|
-
},
|
|
67
|
-
"engines": {
|
|
68
|
-
"node": ">=18.17",
|
|
69
|
-
"pnpm": ">=9"
|
|
70
|
-
},
|
|
71
|
-
"packageManager": "pnpm@11.3.0",
|
|
72
|
-
"files": [
|
|
73
|
-
"dist",
|
|
74
|
-
"templates",
|
|
75
|
-
"docs/manuals",
|
|
76
|
-
"docs/SQ.md",
|
|
77
|
-
"docs/SQ_BY_STEP.yaml",
|
|
78
|
-
"docs/doctrine",
|
|
79
|
-
"src/i18n/catalogs",
|
|
80
|
-
"yujin-design-system",
|
|
81
|
-
"yujin-design-system-artdeco",
|
|
82
|
-
"yujin-design-system-moderna",
|
|
83
|
-
"yujin-design-system-marina",
|
|
84
|
-
"README.md",
|
|
85
|
-
"LICENSE"
|
|
86
|
-
],
|
|
87
|
-
"keywords": [
|
|
88
|
-
"nac",
|
|
89
|
-
"nac-3",
|
|
90
|
-
"react",
|
|
91
|
-
"framework",
|
|
92
|
-
"claude-code",
|
|
93
|
-
"yujin",
|
|
94
|
-
"voice",
|
|
95
|
-
"whisper",
|
|
96
|
-
"elevenlabs",
|
|
97
|
-
"tts",
|
|
98
|
-
"stt",
|
|
99
|
-
"document-reader",
|
|
100
|
-
"pdf",
|
|
101
|
-
"docx",
|
|
102
|
-
"epub",
|
|
103
|
-
"spec-ingest",
|
|
104
|
-
"scaffolding",
|
|
105
|
-
"accessibility",
|
|
106
|
-
"voice-first",
|
|
107
|
-
"adip"
|
|
108
|
-
],
|
|
109
|
-
"repository": {
|
|
110
|
-
"type": "git",
|
|
111
|
-
"url": "git+https://github.com/yujinapp/yujin-forge.git"
|
|
112
|
-
},
|
|
113
|
-
"publishConfig": {
|
|
114
|
-
"access": "public",
|
|
115
|
-
"tag": "latest"
|
|
116
|
-
}
|
|
117
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@nac3/forge-cli",
|
|
3
|
+
"version": "1.11.0",
|
|
4
|
+
"description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"author": "Pablo Kuschnirof <pablo@rpaforce.com>",
|
|
7
|
+
"homepage": "https://github.com/yujinapp/yujin-forge#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/yujinapp/yujin-forge/issues"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"yf": "./dist/bin/yf.js"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"version": "node scripts/sync_version.mjs && git add src/version.ts",
|
|
20
|
+
"build": "tsc && node scripts/copy_qa_assets.mjs",
|
|
21
|
+
"dev": "tsx watch src/bin/yf.ts",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"typecheck:all": "pnpm typecheck && pnpm --filter @yujin/hito4-server typecheck && pnpm --filter @yujin/forge-mobile typecheck",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"yf": "tsx src/bin/yf.ts",
|
|
28
|
+
"catalog:lint": "node scripts/catalog_lint.mjs",
|
|
29
|
+
"pairing:check": "node scripts/check_pairing_sync.mjs",
|
|
30
|
+
"brain-matrix:gate": "node scripts/brain_matrix_gate.mjs",
|
|
31
|
+
"hito4:lint": "node scripts/hito4_lint_bundle.mjs",
|
|
32
|
+
"publish-alpha-emergency": "node scripts/publish_alpha_emergency.mjs",
|
|
33
|
+
"prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run catalog:lint && pnpm run test && pnpm run brain-matrix:gate && pnpm run hito4:lint"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@anthropic-ai/sdk": "^0.32.1",
|
|
37
|
+
"@aws-sdk/client-ecs": "^3.1053.0",
|
|
38
|
+
"@noble/ciphers": "^2.2.0",
|
|
39
|
+
"@noble/hashes": "^2.2.0",
|
|
40
|
+
"@scure/base": "^2.2.0",
|
|
41
|
+
"better-sqlite3": "^12.10.0",
|
|
42
|
+
"commander": "12.1.0",
|
|
43
|
+
"cross-spawn": "^7.0.6",
|
|
44
|
+
"dotenv": "^17.4.2",
|
|
45
|
+
"kleur": "4.1.5",
|
|
46
|
+
"mammoth": "^1.8.0",
|
|
47
|
+
"node-html-parser": "6.1.13",
|
|
48
|
+
"pdfjs-dist": "^4.10.38",
|
|
49
|
+
"prompts": "2.4.2",
|
|
50
|
+
"qrcode": "^1.5.4",
|
|
51
|
+
"typescript": "5.7.2",
|
|
52
|
+
"xlsx": "npm:@e965/xlsx@0.20.3"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@playwright/test": "^1.60.0",
|
|
56
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
57
|
+
"@types/cross-spawn": "^6.0.6",
|
|
58
|
+
"@types/node": "22.10.2",
|
|
59
|
+
"@types/prompts": "2.4.9",
|
|
60
|
+
"@types/qrcode": "^1.5.6",
|
|
61
|
+
"acorn": "^8.16.0",
|
|
62
|
+
"pixelmatch": "^7.2.0",
|
|
63
|
+
"pngjs": "^7.0.0",
|
|
64
|
+
"tsx": "4.19.2",
|
|
65
|
+
"vitest": "2.1.8"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18.17",
|
|
69
|
+
"pnpm": ">=9"
|
|
70
|
+
},
|
|
71
|
+
"packageManager": "pnpm@11.3.0",
|
|
72
|
+
"files": [
|
|
73
|
+
"dist",
|
|
74
|
+
"templates",
|
|
75
|
+
"docs/manuals",
|
|
76
|
+
"docs/SQ.md",
|
|
77
|
+
"docs/SQ_BY_STEP.yaml",
|
|
78
|
+
"docs/doctrine",
|
|
79
|
+
"src/i18n/catalogs",
|
|
80
|
+
"yujin-design-system",
|
|
81
|
+
"yujin-design-system-artdeco",
|
|
82
|
+
"yujin-design-system-moderna",
|
|
83
|
+
"yujin-design-system-marina",
|
|
84
|
+
"README.md",
|
|
85
|
+
"LICENSE"
|
|
86
|
+
],
|
|
87
|
+
"keywords": [
|
|
88
|
+
"nac",
|
|
89
|
+
"nac-3",
|
|
90
|
+
"react",
|
|
91
|
+
"framework",
|
|
92
|
+
"claude-code",
|
|
93
|
+
"yujin",
|
|
94
|
+
"voice",
|
|
95
|
+
"whisper",
|
|
96
|
+
"elevenlabs",
|
|
97
|
+
"tts",
|
|
98
|
+
"stt",
|
|
99
|
+
"document-reader",
|
|
100
|
+
"pdf",
|
|
101
|
+
"docx",
|
|
102
|
+
"epub",
|
|
103
|
+
"spec-ingest",
|
|
104
|
+
"scaffolding",
|
|
105
|
+
"accessibility",
|
|
106
|
+
"voice-first",
|
|
107
|
+
"adip"
|
|
108
|
+
],
|
|
109
|
+
"repository": {
|
|
110
|
+
"type": "git",
|
|
111
|
+
"url": "git+https://github.com/yujinapp/yujin-forge.git"
|
|
112
|
+
},
|
|
113
|
+
"publishConfig": {
|
|
114
|
+
"access": "public",
|
|
115
|
+
"tag": "latest"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "رسم بياني مرئي",
|
|
186
186
|
"startup.tab.graphSem": "الرسم الدلالي",
|
|
187
187
|
"startup.tab.pendings": "معلق",
|
|
188
|
+
"startup.tab.done": "منجز",
|
|
188
189
|
"startup.tab.workflow": "سير العمل",
|
|
189
190
|
"settings.startupTabs": "علامات التبويب عند الفتح",
|
|
190
191
|
"graph.term.nodes": "عقد",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Visuelles Diagramm",
|
|
186
186
|
"startup.tab.graphSem": "Semantischer Graph",
|
|
187
187
|
"startup.tab.pendings": "Ausstehend",
|
|
188
|
+
"startup.tab.done": "Erledigt",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Tabs beim Start (Graph, ausstehend, Workflow)",
|
|
190
191
|
"graph.term.nodes": "Knoten",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Visual graph",
|
|
186
186
|
"startup.tab.graphSem": "Semantic graph",
|
|
187
187
|
"startup.tab.pendings": "Pendings",
|
|
188
|
+
"startup.tab.done": "Done",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Tabs on open (graph, pendings, workflow)",
|
|
190
191
|
"graph.term.nodes": "nodes",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Grafo grafico",
|
|
186
186
|
"startup.tab.graphSem": "Grafo semantico",
|
|
187
187
|
"startup.tab.pendings": "Pendientes",
|
|
188
|
+
"startup.tab.done": "Hecho",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Pestanas al abrir (grafo, pendings, workflow)",
|
|
190
191
|
"graph.term.nodes": "nodos",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Graphe visuel",
|
|
186
186
|
"startup.tab.graphSem": "Graphe semantique",
|
|
187
187
|
"startup.tab.pendings": "En attente",
|
|
188
|
+
"startup.tab.done": "Termine",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Onglets a l'ouverture (graphe, en attente, workflow)",
|
|
190
191
|
"graph.term.nodes": "noeuds",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "विज़ुअल ग्राफ़",
|
|
186
186
|
"startup.tab.graphSem": "सिमेंटिक ग्राफ़",
|
|
187
187
|
"startup.tab.pendings": "लंबित",
|
|
188
|
+
"startup.tab.done": "पूर्ण",
|
|
188
189
|
"startup.tab.workflow": "वर्कफ़्लो",
|
|
189
190
|
"settings.startupTabs": "खुलने पर टैब",
|
|
190
191
|
"graph.term.nodes": "नोड",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Grafo visuale",
|
|
186
186
|
"startup.tab.graphSem": "Grafo semantico",
|
|
187
187
|
"startup.tab.pendings": "In sospeso",
|
|
188
|
+
"startup.tab.done": "Fatto",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Schede all'avvio (grafo, in sospeso, workflow)",
|
|
190
191
|
"graph.term.nodes": "nodi",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "グラフ(図)",
|
|
186
186
|
"startup.tab.graphSem": "セマンティックグラフ",
|
|
187
187
|
"startup.tab.pendings": "保留中",
|
|
188
|
+
"startup.tab.done": "完了",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "起動時のタブ(グラフ、保留、ワークフロー)",
|
|
190
191
|
"graph.term.nodes": "ノード",
|
|
@@ -185,6 +185,7 @@
|
|
|
185
185
|
"startup.tab.graph": "Grafo visual",
|
|
186
186
|
"startup.tab.graphSem": "Grafo semantico",
|
|
187
187
|
"startup.tab.pendings": "Pendencias",
|
|
188
|
+
"startup.tab.done": "Concluido",
|
|
188
189
|
"startup.tab.workflow": "Workflow",
|
|
189
190
|
"settings.startupTabs": "Abas ao abrir (grafo, pendencias, workflow)",
|
|
190
191
|
"graph.term.nodes": "nos",
|