@nac3/forge-cli 1.0.13 → 1.0.15
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.js +15 -0
- package/dist/bin/yf.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +6 -3
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/session_projects.d.ts +6 -2
- package/dist/chat/session_projects.d.ts.map +1 -1
- package/dist/chat/session_projects.js +6 -3
- package/dist/chat/session_projects.js.map +1 -1
- package/dist/license/activate_url.d.ts +36 -0
- package/dist/license/activate_url.d.ts.map +1 -0
- package/dist/license/activate_url.js +76 -0
- package/dist/license/activate_url.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -19,9 +19,13 @@
|
|
|
19
19
|
export interface SessionProject {
|
|
20
20
|
root: string;
|
|
21
21
|
slug: string;
|
|
22
|
+
name: string;
|
|
22
23
|
}
|
|
23
|
-
/** Point a session at its own project (root + slug).
|
|
24
|
-
|
|
24
|
+
/** Point a session at its own project (root + slug + display name).
|
|
25
|
+
* name travels WITH root/slug so a turn's prompt context cannot report
|
|
26
|
+
* the global project's name against the session's directory (Pablo
|
|
27
|
+
* 2026-06-18: chat said "project A" while cwd was project B's path). */
|
|
28
|
+
export declare function setSessionProject(sessionId: string, root: string, slug: string, name: string): void;
|
|
25
29
|
/** The override for a session, or null when it follows the global project. */
|
|
26
30
|
export declare function getSessionProject(sessionId: string): SessionProject | null;
|
|
27
31
|
/** Clear a session's override (back to the global project). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session_projects.d.ts","sourceRoot":"","sources":["../../src/chat/session_projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;
|
|
1
|
+
{"version":3,"file":"session_projects.d.ts","sourceRoot":"","sources":["../../src/chat/session_projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAI5E;;;yEAGyE;AACzE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGnG;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAE1E;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED,iBAAiB;AACjB,wBAAgB,qBAAqB,IAAI,IAAI,CAAwB"}
|
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
* ASCII-only.
|
|
18
18
|
*/
|
|
19
19
|
const _overrides = new Map();
|
|
20
|
-
/** Point a session at its own project (root + slug).
|
|
21
|
-
|
|
20
|
+
/** Point a session at its own project (root + slug + display name).
|
|
21
|
+
* name travels WITH root/slug so a turn's prompt context cannot report
|
|
22
|
+
* the global project's name against the session's directory (Pablo
|
|
23
|
+
* 2026-06-18: chat said "project A" while cwd was project B's path). */
|
|
24
|
+
export function setSessionProject(sessionId, root, slug, name) {
|
|
22
25
|
if (!sessionId)
|
|
23
26
|
return;
|
|
24
|
-
_overrides.set(sessionId, { root, slug });
|
|
27
|
+
_overrides.set(sessionId, { root, slug, name });
|
|
25
28
|
}
|
|
26
29
|
/** The override for a session, or null when it follows the global project. */
|
|
27
30
|
export function getSessionProject(sessionId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session_projects.js","sourceRoot":"","sources":["../../src/chat/session_projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"session_projects.js","sourceRoot":"","sources":["../../src/chat/session_projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;AAErD;;;yEAGyE;AACzE,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,IAAY,EAAE,IAAY,EAAE,IAAY;IAC3F,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,qBAAqB,KAAW,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type FetchLike = (url: string, init: {
|
|
2
|
+
method: string;
|
|
3
|
+
headers: Record<string, string>;
|
|
4
|
+
body: string;
|
|
5
|
+
}) => Promise<{
|
|
6
|
+
ok: boolean;
|
|
7
|
+
status: number;
|
|
8
|
+
json(): Promise<unknown>;
|
|
9
|
+
}>;
|
|
10
|
+
/** Pull the one-time token out of a yujin-forge://activate?token=... URL.
|
|
11
|
+
* Returns null for anything that is not such a URL. */
|
|
12
|
+
export declare function parseActivateUrl(arg: string): string | null;
|
|
13
|
+
export interface RedeemedHandle {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
handle?: string;
|
|
16
|
+
handle_key?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Redeem a provision token at the worker. Pure network -- no local writes,
|
|
20
|
+
* so it is unit-testable with an injected fetch. */
|
|
21
|
+
export declare function redeemToken(token: string, opts?: {
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
fetchImpl?: FetchLike;
|
|
24
|
+
}): Promise<RedeemedHandle>;
|
|
25
|
+
export interface ActivateUrlResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
handle?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Full activation: parse -> redeem -> persist the per-handle key + handle. */
|
|
31
|
+
export declare function activateFromUrl(arg: string, opts?: {
|
|
32
|
+
baseUrl?: string;
|
|
33
|
+
fetchImpl?: FetchLike;
|
|
34
|
+
}): Promise<ActivateUrlResult>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=activate_url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activate_url.d.ts","sourceRoot":"","sources":["../../src/license/activate_url.ts"],"names":[],"mappings":"AAmBA,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC;IACjH,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD,CAAC,CAAC;AAEH;wDACwD;AACxD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAED,MAAM,WAAW,cAAc;IAAG,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAErG;qDACqD;AACrD,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAkBzB;AAED,MAAM,WAAW,iBAAiB;IAAG,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAEnF,+EAA+E;AAC/E,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GACjD,OAAO,CAAC,iBAAiB,CAAC,CAU5B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* yujin-forge:// protocol activation -- PND-129 Camino A (zero friction).
|
|
3
|
+
*
|
|
4
|
+
* After the buyer clicks "Open Forge" on the Polar success page, the OS
|
|
5
|
+
* launches the registered handler with a URL like
|
|
6
|
+
* yujin-forge://activate?token=<one-time provision token>
|
|
7
|
+
* as an argv entry. We redeem that token at the worker for THIS handle's
|
|
8
|
+
* per-handle key (HKDF, derived server-side -- the client never sees the
|
|
9
|
+
* global root), store it, and mark the local license active. The user
|
|
10
|
+
* pasted nothing and ran no command.
|
|
11
|
+
*
|
|
12
|
+
* ASCII-only.
|
|
13
|
+
*/
|
|
14
|
+
import { Vault } from '../vault/store.js';
|
|
15
|
+
import { configDir } from './index.js';
|
|
16
|
+
import { HANDLE_KEY_SLOT } from './handle_key.js';
|
|
17
|
+
import { HITO4_BASE_URL } from './hito4_client.js';
|
|
18
|
+
import { readLicense, writeLicense } from '../core/polar.js';
|
|
19
|
+
/** Pull the one-time token out of a yujin-forge://activate?token=... URL.
|
|
20
|
+
* Returns null for anything that is not such a URL. */
|
|
21
|
+
export function parseActivateUrl(arg) {
|
|
22
|
+
if (typeof arg !== 'string' || !arg.startsWith('yujin-forge://'))
|
|
23
|
+
return null;
|
|
24
|
+
let u;
|
|
25
|
+
try {
|
|
26
|
+
u = new URL(arg);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/* host is "activate" (yujin-forge://activate?token=...). Accept any host
|
|
32
|
+
* but require the activate intent + a token, so a future verb cannot be
|
|
33
|
+
* mistaken for an activation. */
|
|
34
|
+
const action = (u.hostname || u.pathname.replace(/^\/+/, '')).toLowerCase();
|
|
35
|
+
if (action !== 'activate')
|
|
36
|
+
return null;
|
|
37
|
+
const token = (u.searchParams.get('token') || '').trim();
|
|
38
|
+
return token.length >= 32 ? token : null;
|
|
39
|
+
}
|
|
40
|
+
/** Redeem a provision token at the worker. Pure network -- no local writes,
|
|
41
|
+
* so it is unit-testable with an injected fetch. */
|
|
42
|
+
export async function redeemToken(token, opts) {
|
|
43
|
+
const base = opts?.baseUrl ?? HITO4_BASE_URL;
|
|
44
|
+
const f = opts?.fetchImpl ?? globalThis.fetch;
|
|
45
|
+
let resp;
|
|
46
|
+
try {
|
|
47
|
+
resp = await f(base + '/v1/provision/redeem', {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: { 'content-type': 'application/json' },
|
|
50
|
+
body: JSON.stringify({ token }),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return { ok: false, error: 'network error: ' + (e instanceof Error ? e.message : String(e)) };
|
|
55
|
+
}
|
|
56
|
+
const j = (await resp.json().catch(() => ({})));
|
|
57
|
+
if (!resp.ok || !j.ok || !j.handle || !j.handle_key) {
|
|
58
|
+
return { ok: false, error: j.error || ('redeem failed (' + resp.status + ')') };
|
|
59
|
+
}
|
|
60
|
+
return { ok: true, handle: j.handle, handle_key: j.handle_key };
|
|
61
|
+
}
|
|
62
|
+
/** Full activation: parse -> redeem -> persist the per-handle key + handle. */
|
|
63
|
+
export async function activateFromUrl(arg, opts) {
|
|
64
|
+
const token = parseActivateUrl(arg);
|
|
65
|
+
if (!token)
|
|
66
|
+
return { ok: false, error: 'not a valid yujin-forge://activate token URL' };
|
|
67
|
+
const red = await redeemToken(token, opts);
|
|
68
|
+
if (!red.ok || !red.handle || !red.handle_key)
|
|
69
|
+
return { ok: false, error: red.error };
|
|
70
|
+
const vault = await Vault.open({ configDir: configDir() });
|
|
71
|
+
await vault.set(HANDLE_KEY_SLOT, red.handle_key);
|
|
72
|
+
const cur = await readLicense();
|
|
73
|
+
await writeLicense({ ...cur, user_handle: red.handle });
|
|
74
|
+
return { ok: true, handle: red.handle };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=activate_url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activate_url.js","sourceRoot":"","sources":["../../src/license/activate_url.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Yujin Forge CLI version. Kept in sync with package.json by the npm
|
|
3
3
|
* "version" lifecycle (scripts/sync_version.mjs) so the two never drift.
|
|
4
4
|
*/
|
|
5
|
-
export declare const VERSION = "1.0.
|
|
5
|
+
export declare const VERSION = "1.0.15";
|
|
6
6
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nac3/forge-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
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>",
|