@nac3/forge-cli 0.2.0-alpha.3 → 0.2.0-alpha.5
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/bin/yf.d.ts.map +1 -1
- package/dist/bin/yf.js +4 -0
- package/dist/bin/yf.js.map +1 -1
- package/dist/chat/panel.js +2 -2
- package/dist/chat/server.js +9 -9
- package/dist/chat/tools/git.js +4 -4
- package/dist/chat/tools/github.js +3 -3
- package/dist/chat/tools/lifecycle.js +3 -3
- package/dist/chat/tools/manual.js +1 -1
- package/dist/chat/tools/reader.js +8 -8
- package/dist/chat/tools.js +4 -4
- package/dist/commands/doctor.js +94 -42
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/keys_setup.d.ts +53 -0
- package/dist/commands/keys_setup.d.ts.map +1 -0
- package/dist/commands/keys_setup.js +487 -0
- package/dist/commands/keys_setup.js.map +1 -0
- package/dist/commands/voice.js +1 -1
- package/dist/commands/voice.js.map +1 -1
- package/dist/core/keys_envelope.d.ts +13 -0
- package/dist/core/keys_envelope.d.ts.map +1 -1
- package/dist/core/keys_envelope.js.map +1 -1
- package/dist/license/hito4_client.d.ts +17 -1
- package/dist/license/hito4_client.d.ts.map +1 -1
- package/dist/license/hito4_client.js +71 -10
- package/dist/license/hito4_client.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/intents.d.ts +1 -1
- package/dist/voice/intents.js +0 -0
- package/package.json +2 -2
|
@@ -19,11 +19,63 @@
|
|
|
19
19
|
* ASCII-only.
|
|
20
20
|
*/
|
|
21
21
|
import { createHmac } from 'node:crypto';
|
|
22
|
+
import { promises as fs } from 'node:fs';
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
import os from 'node:os';
|
|
22
25
|
import { Vault } from '../vault/store.js';
|
|
23
26
|
import { configDir } from './index.js';
|
|
24
27
|
import { readLicense } from '../core/polar.js';
|
|
25
28
|
export const HITO4_BASE_URL = process.env.YF_HITO4_BASE_URL ?? 'https://yujin-hito4.yujinapp.workers.dev';
|
|
26
29
|
const SECRET_SLOT = 'yf_server_api_key';
|
|
30
|
+
/** Read the local plaintext provider keys cache. The mobile
|
|
31
|
+
* equivalent is the `useProviderKeys` hook. Returns null if
|
|
32
|
+
* the file does not exist yet (user has not run keys setup). */
|
|
33
|
+
async function readLocalProviderKeys() {
|
|
34
|
+
const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
35
|
+
const p = path.join(home, '.yujin-forge', 'provider_keys.json');
|
|
36
|
+
try {
|
|
37
|
+
const raw = await fs.readFile(p, 'utf-8');
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
if (parsed && parsed.v === 1)
|
|
40
|
+
return parsed;
|
|
41
|
+
}
|
|
42
|
+
catch { /* missing */ }
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/** Resolve which brain provider + key + model alias to use for
|
|
46
|
+
* the current request. Mirrors the mobile-side logic that
|
|
47
|
+
* reads from the encrypted keys-sync cache. */
|
|
48
|
+
export async function resolveBrainHeaders() {
|
|
49
|
+
const cache = await readLocalProviderKeys();
|
|
50
|
+
if (!cache)
|
|
51
|
+
return { provider: null, apiKey: null, modelAlias: null };
|
|
52
|
+
const provider = (cache.brain_provider_preference ?? null);
|
|
53
|
+
if (!provider)
|
|
54
|
+
return { provider: null, apiKey: null, modelAlias: null };
|
|
55
|
+
let apiKey;
|
|
56
|
+
let modelAlias;
|
|
57
|
+
if (provider === 'anthropic') {
|
|
58
|
+
apiKey = cache.anthropic_api_key;
|
|
59
|
+
modelAlias = cache.anthropic_model_preference;
|
|
60
|
+
}
|
|
61
|
+
else if (provider === 'openai') {
|
|
62
|
+
apiKey = cache.openai_api_key;
|
|
63
|
+
modelAlias = cache.openai_brain_model_preference;
|
|
64
|
+
}
|
|
65
|
+
else if (provider === 'google') {
|
|
66
|
+
apiKey = cache.google_ai_key;
|
|
67
|
+
modelAlias = cache.google_brain_model_preference;
|
|
68
|
+
}
|
|
69
|
+
else if (provider === 'deepseek') {
|
|
70
|
+
apiKey = cache.deepseek_api_key;
|
|
71
|
+
modelAlias = cache.deepseek_model_preference;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
provider,
|
|
75
|
+
apiKey: apiKey ?? null,
|
|
76
|
+
modelAlias: modelAlias ?? null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
27
79
|
function hmacHex(secret, msg) {
|
|
28
80
|
return createHmac('sha256', secret).update(msg).digest('hex');
|
|
29
81
|
}
|
|
@@ -52,23 +104,32 @@ export function signBearer(secret, handle, ts = Date.now()) {
|
|
|
52
104
|
return ts + '.' + sig;
|
|
53
105
|
}
|
|
54
106
|
/** Call a HITO 4 flow. Returns the raw server response (no
|
|
55
|
-
* retry / no backoff -- callers can decide).
|
|
107
|
+
* retry / no backoff -- callers can decide).
|
|
108
|
+
*
|
|
109
|
+
* Brain providers are BYOK: this call reads the local
|
|
110
|
+
* ~/.yujin-forge/provider_keys.json, picks the preferred
|
|
111
|
+
* provider + key + model, and forwards them as headers. The
|
|
112
|
+
* worker never persists nor logs the key. */
|
|
56
113
|
export async function callFlow(flow, input, deps = {}) {
|
|
57
114
|
const base = deps.baseUrl ?? HITO4_BASE_URL;
|
|
58
115
|
const secret = await getSecret(deps);
|
|
59
116
|
const handle = await getHandle(deps);
|
|
60
117
|
const bearer = signBearer(secret, handle);
|
|
61
118
|
const fetchImpl = deps.fetchImpl ?? ((u, init) => globalThis.fetch(u, init));
|
|
119
|
+
const brain = await resolveBrainHeaders();
|
|
62
120
|
const url = base.replace(/\/+$/, '') + '/v1/flows/' + encodeURIComponent(flow);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
121
|
+
const headers = {
|
|
122
|
+
'Authorization': 'Bearer ' + bearer,
|
|
123
|
+
'x-yf-user-handle': handle,
|
|
124
|
+
'content-type': 'application/json',
|
|
125
|
+
};
|
|
126
|
+
if (brain.provider)
|
|
127
|
+
headers['x-yf-brain-provider'] = brain.provider;
|
|
128
|
+
if (brain.apiKey)
|
|
129
|
+
headers['x-yf-brain-key'] = brain.apiKey;
|
|
130
|
+
if (brain.modelAlias)
|
|
131
|
+
headers['x-yf-brain-model'] = brain.modelAlias;
|
|
132
|
+
const r = await fetchImpl(url, { method: 'POST', headers, body: JSON.stringify(input ?? null) });
|
|
72
133
|
let body = {};
|
|
73
134
|
try {
|
|
74
135
|
body = await r.json();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hito4_client.js","sourceRoot":"","sources":["../../src/license/hito4_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"hito4_client.js","sourceRoot":"","sources":["../../src/license/hito4_client.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/voice/intents.d.ts
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* the contract is the literal string the chat dispatcher
|
|
36
36
|
* accepts. If a tool is renamed there, this list must follow.
|
|
37
37
|
*/
|
|
38
|
-
export type ReaderToolName = '
|
|
38
|
+
export type ReaderToolName = 'forge_reader_open' | 'forge_reader_list_documents' | 'forge_reader_read_section' | 'forge_reader_next_block' | 'forge_reader_search' | 'forge_reader_bookmark_set' | 'forge_reader_bookmark_jump' | 'forge_reader_recap' | 'forge_manual_open';
|
|
39
39
|
export interface MatchedIntent {
|
|
40
40
|
tool: ReaderToolName;
|
|
41
41
|
args: Record<string, unknown>;
|
package/dist/voice/intents.js
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nac3/forge-cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.5",
|
|
4
4
|
"description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Pablo Kuschnirof <pablo@rpaforce.com>",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=18.17",
|
|
53
|
-
"pnpm": ">=
|
|
53
|
+
"pnpm": ">=9"
|
|
54
54
|
},
|
|
55
55
|
"packageManager": "pnpm@11.3.0",
|
|
56
56
|
"files": [
|