@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.
@@ -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
- export declare function setSessionProject(sessionId: string, root: string, slug: string): void;
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;AAI9D,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGrF;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"}
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
- export function setSessionProject(sessionId, root, slug) {
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,wDAAwD;AACxD,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,IAAY,EAAE,IAAY;IAC7E,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5C,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"}
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.13";
5
+ export declare const VERSION = "1.0.15";
6
6
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js 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 const VERSION = '1.0.13';
5
+ export const VERSION = '1.0.15';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nac3/forge-cli",
3
- "version": "1.0.13",
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>",