@nac3/forge-cli 1.19.1 → 1.19.3
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 +2 -0
- package/dist/bin/yf.js.map +1 -1
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +198 -2
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +136 -2
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/tools/session_verbs.d.ts +10 -0
- package/dist/chat/tools/session_verbs.d.ts.map +1 -1
- package/dist/chat/tools/session_verbs.js +22 -12
- package/dist/chat/tools/session_verbs.js.map +1 -1
- package/dist/chat/tools/urazuke.d.ts +4 -0
- package/dist/chat/tools/urazuke.d.ts.map +1 -1
- package/dist/chat/tools/urazuke.js +21 -0
- package/dist/chat/tools/urazuke.js.map +1 -1
- package/dist/chat/tools.d.ts.map +1 -1
- package/dist/chat/tools.js +22 -0
- package/dist/chat/tools.js.map +1 -1
- package/dist/chat/urazuke_section.d.ts +1 -0
- package/dist/chat/urazuke_section.d.ts.map +1 -1
- package/dist/chat/urazuke_section.js +1 -0
- package/dist/chat/urazuke_section.js.map +1 -1
- package/dist/commands/task.d.ts +18 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +126 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/urazuke.d.ts.map +1 -1
- package/dist/commands/urazuke.js +29 -0
- package/dist/commands/urazuke.js.map +1 -1
- package/dist/mcp/bridge_registry.d.ts +1 -1
- package/dist/nac3/dispatch_log.d.ts.map +1 -1
- package/dist/nac3/dispatch_log.js +16 -11
- package/dist/nac3/dispatch_log.js.map +1 -1
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +43 -0
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/tasks/alive.d.ts +38 -0
- package/dist/tasks/alive.d.ts.map +1 -0
- package/dist/tasks/alive.js +66 -0
- package/dist/tasks/alive.js.map +1 -0
- package/dist/urazuke/announce.d.ts +21 -0
- package/dist/urazuke/announce.d.ts.map +1 -0
- package/dist/urazuke/announce.js +40 -0
- package/dist/urazuke/announce.js.map +1 -0
- package/dist/urazuke/current.d.ts +25 -1
- package/dist/urazuke/current.d.ts.map +1 -1
- package/dist/urazuke/current.js +38 -3
- package/dist/urazuke/current.js.map +1 -1
- package/dist/urazuke/gate.d.ts +5 -0
- package/dist/urazuke/gate.d.ts.map +1 -1
- package/dist/urazuke/gate.js +7 -5
- package/dist/urazuke/gate.js.map +1 -1
- package/dist/urazuke/section.d.ts.map +1 -1
- package/dist/urazuke/section.js +1 -0
- package/dist/urazuke/section.js.map +1 -1
- package/dist/urazuke/start.d.ts +64 -0
- package/dist/urazuke/start.d.ts.map +1 -0
- package/dist/urazuke/start.js +91 -0
- package/dist/urazuke/start.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/chat/server.js
CHANGED
|
@@ -1777,6 +1777,89 @@ async function route(req, res, ctx) {
|
|
|
1777
1777
|
}
|
|
1778
1778
|
return;
|
|
1779
1779
|
}
|
|
1780
|
+
/* One project document, for the links of the Urazuke card modal. Gated to
|
|
1781
|
+
* the project root: a path that escapes it is refused. */
|
|
1782
|
+
if (req.method === 'GET' && url.pathname === '/api/forge/project-doc') {
|
|
1783
|
+
const rel = (url.searchParams.get('path') || '').trim();
|
|
1784
|
+
if (!rel) {
|
|
1785
|
+
sendJson(res, 400, { ok: false, error: 'path required' });
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
try {
|
|
1789
|
+
const nodePath = await import('node:path');
|
|
1790
|
+
const fsp = await import('node:fs/promises');
|
|
1791
|
+
const abs = nodePath.resolve(ctx.projectRoot, rel);
|
|
1792
|
+
const inside = abs === ctx.projectRoot || abs.startsWith(ctx.projectRoot + nodePath.sep);
|
|
1793
|
+
if (!inside) {
|
|
1794
|
+
sendJson(res, 403, { ok: false, error: 'path outside the project' });
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
const st = await fsp.stat(abs);
|
|
1798
|
+
if (!st.isFile()) {
|
|
1799
|
+
sendJson(res, 404, { ok: false, error: 'not a file' });
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1802
|
+
if (st.size > 2 * 1024 * 1024) {
|
|
1803
|
+
sendJson(res, 413, { ok: false, error: 'file too big for the panel (2 MB)' });
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
const content = await fsp.readFile(abs, 'utf8');
|
|
1807
|
+
const ext = nodePath.extname(abs).replace('.', '').toLowerCase();
|
|
1808
|
+
sendJson(res, 200, { ok: true, path: nodePath.relative(ctx.projectRoot, abs).split(nodePath.sep).join('/'), content, language: ext || null });
|
|
1809
|
+
}
|
|
1810
|
+
catch (e) {
|
|
1811
|
+
sendJson(res, 404, { ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
1812
|
+
}
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
/* One pending item in full, for the click on a Workflow task. */
|
|
1816
|
+
if (req.method === 'GET' && url.pathname === '/api/forge/pending-item') {
|
|
1817
|
+
const id = (url.searchParams.get('id') || '').trim();
|
|
1818
|
+
if (!id) {
|
|
1819
|
+
sendJson(res, 400, { ok: false, error: 'id required' });
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
try {
|
|
1823
|
+
const { findPending } = await import('../pending/store.js');
|
|
1824
|
+
const item = await findPending(ctx.projectSlug || '', id);
|
|
1825
|
+
if (!item) {
|
|
1826
|
+
sendJson(res, 404, { ok: false, error: 'pending ' + id + ' not found' });
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
sendJson(res, 200, { ok: true, item });
|
|
1830
|
+
}
|
|
1831
|
+
catch (e) {
|
|
1832
|
+
sendJson(res, 500, { ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
1833
|
+
}
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
/* URAZUKE start (2026-10-19): the panel button. */
|
|
1837
|
+
if (req.method === 'POST' && url.pathname === '/api/forge/urazuke-start') {
|
|
1838
|
+
let body = {};
|
|
1839
|
+
try {
|
|
1840
|
+
body = JSON.parse(await readBody(req) || '{}');
|
|
1841
|
+
}
|
|
1842
|
+
catch {
|
|
1843
|
+
body = {};
|
|
1844
|
+
}
|
|
1845
|
+
try {
|
|
1846
|
+
const { startUrazuke } = await import('../urazuke/start.js');
|
|
1847
|
+
const r = await startUrazuke(ctx.projectSlug || '', ctx.projectRoot, { force: body.force === true });
|
|
1848
|
+
if (r.ok) {
|
|
1849
|
+
try {
|
|
1850
|
+
const { urazukeCurrent } = await import('../urazuke/current.js');
|
|
1851
|
+
const { announceStepIfChanged } = await import('../urazuke/announce.js');
|
|
1852
|
+
await announceStepIfChanged(ctx.projectSlug || '', await urazukeCurrent(ctx.projectSlug || '', ctx.projectRoot));
|
|
1853
|
+
}
|
|
1854
|
+
catch { /* best effort */ }
|
|
1855
|
+
}
|
|
1856
|
+
sendJson(res, r.ok ? 200 : 409, { ...r });
|
|
1857
|
+
}
|
|
1858
|
+
catch (e) {
|
|
1859
|
+
sendJson(res, 500, { ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
1860
|
+
}
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1780
1863
|
if (req.method === 'POST' && url.pathname === '/api/forge/urazuke-prompts') {
|
|
1781
1864
|
let body;
|
|
1782
1865
|
try {
|
|
@@ -4594,6 +4677,8 @@ async function handleMobilePair(_req, res) {
|
|
|
4594
4677
|
* Devuelve {enabled, tabs:[{key,title,kind,content}]}. El panel
|
|
4595
4678
|
* las materializa al abrir (salvo las que el usuario cerro) y
|
|
4596
4679
|
* hace polling para auto-refrescarlas. */
|
|
4680
|
+
/* One leftover-tasks notice per panel process (2026-10-20). */
|
|
4681
|
+
let leftoverTasksAnnounced = false;
|
|
4597
4682
|
async function handleStartupTabs(_req, res, ctx, url) {
|
|
4598
4683
|
const slug = ctx.projectSlug || '';
|
|
4599
4684
|
let enabled = true;
|
|
@@ -4702,7 +4787,17 @@ async function handleStartupTabs(_req, res, ctx, url) {
|
|
|
4702
4787
|
catch {
|
|
4703
4788
|
ladderActive = false;
|
|
4704
4789
|
}
|
|
4705
|
-
|
|
4790
|
+
let urazukeOn = false;
|
|
4791
|
+
try {
|
|
4792
|
+
urazukeOn = await (await import('../urazuke/enabled.js')).urazukeEnabled();
|
|
4793
|
+
}
|
|
4794
|
+
catch {
|
|
4795
|
+
urazukeOn = false;
|
|
4796
|
+
}
|
|
4797
|
+
if (ladderActive)
|
|
4798
|
+
hidden.push('startup_workflow');
|
|
4799
|
+
else if (!urazukeOn)
|
|
4800
|
+
hidden.push('startup_urazuke');
|
|
4706
4801
|
/* 4: workflow como GRAFO de nodos (las 6 fases del flujo yujin
|
|
4707
4802
|
* con sus pasos), coloreadas por estado (done/pendiente) cuando
|
|
4708
4803
|
* hay workflow state. Cumple el pedido de "workflow como grafo
|
|
@@ -4749,6 +4844,12 @@ async function handleStartupTabs(_req, res, ctx, url) {
|
|
|
4749
4844
|
} : null;
|
|
4750
4845
|
tabs.push({ key: 'startup_urazuke', title: t('startup.tab.urazuke'), kind: 'urazuke', content: JSON.stringify({ ladder, current }) });
|
|
4751
4846
|
}
|
|
4847
|
+
else if (slugU && urazukeOn) {
|
|
4848
|
+
/* No ladder yet: the tab offers the door in (yujin.urazuke.start). */
|
|
4849
|
+
const { urazukeStartHint } = await import('../urazuke/start.js');
|
|
4850
|
+
const start = await urazukeStartHint(slugU, ctx.projectRoot);
|
|
4851
|
+
tabs.push({ key: 'startup_urazuke', title: t('startup.tab.urazuke'), kind: 'urazuke', content: JSON.stringify({ ladder: null, current: null, start }) });
|
|
4852
|
+
}
|
|
4752
4853
|
}
|
|
4753
4854
|
catch { /* sin escalera: la pestana no aparece */ }
|
|
4754
4855
|
/* 5: PND-007 -- Tareas de fondo (se llena en vivo client-side). */
|
|
@@ -6206,12 +6307,37 @@ async function handleChat(req, res, ctx) {
|
|
|
6206
6307
|
* the mechanical state of its checks, injected every turn. This is the
|
|
6207
6308
|
* mechanism that replaces the advisory 18-step flow: the brain gets the
|
|
6208
6309
|
* method's exact instruction, and the close gate refuses a red step. */
|
|
6310
|
+
/* Live background tasks (2026-10-20): the brain sees what is still up so
|
|
6311
|
+
* it does not relaunch it, and the owner gets one notice when the panel
|
|
6312
|
+
* opens with servers left over from another session. */
|
|
6313
|
+
let liveTasksSection = '';
|
|
6314
|
+
try {
|
|
6315
|
+
const { liveTasks, renderLiveTasksSection, renderLeftoverNotice } = await import('../tasks/alive.js');
|
|
6316
|
+
const live = await liveTasks(ctx.projectSlug || '');
|
|
6317
|
+
liveTasksSection = renderLiveTasksSection(live);
|
|
6318
|
+
if (!leftoverTasksAnnounced) {
|
|
6319
|
+
leftoverTasksAnnounced = true;
|
|
6320
|
+
const notice = renderLeftoverNotice(live);
|
|
6321
|
+
if (notice) {
|
|
6322
|
+
const { enqueuePanelDispatch } = await import('./panel_queue.js');
|
|
6323
|
+
enqueuePanelDispatch('system.chat-log', { text: notice }, new Date().toISOString());
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
6326
|
+
}
|
|
6327
|
+
catch (_) { /* swallow */ }
|
|
6209
6328
|
let urazukeSection = '';
|
|
6210
6329
|
try {
|
|
6211
6330
|
const { buildUrazukeSection } = await import('./urazuke_section.js');
|
|
6212
6331
|
const r = await buildUrazukeSection({ project_slug: ctx.projectSlug || '', project_root: ctx.projectRoot, char_budget: 6000 });
|
|
6213
6332
|
if (r.rendered_text)
|
|
6214
6333
|
urazukeSection = r.rendered_text;
|
|
6334
|
+
/* The owner sees in the chat which step runs and what is expected of
|
|
6335
|
+
* them (never the prompt): one system line per step change. */
|
|
6336
|
+
try {
|
|
6337
|
+
const { announceStepIfChanged } = await import('../urazuke/announce.js');
|
|
6338
|
+
await announceStepIfChanged(ctx.projectSlug || '', r.current);
|
|
6339
|
+
}
|
|
6340
|
+
catch { /* best effort */ }
|
|
6215
6341
|
}
|
|
6216
6342
|
catch (_) { /* swallow */ }
|
|
6217
6343
|
/* alpha.59z.15 HITO 6.3 -- prefetch global learnings from
|
|
@@ -6245,6 +6371,14 @@ async function handleChat(req, res, ctx) {
|
|
|
6245
6371
|
try {
|
|
6246
6372
|
const { readLimitsConfig } = await import('../core/limits_config.js');
|
|
6247
6373
|
multiagentEnabled = (await readLimitsConfig()).multiagent.enabled === true;
|
|
6374
|
+
/* 2026-10-19: on the Claude Plan without another provider's key the
|
|
6375
|
+
* children cannot run; hide the verbs instead of letting the brain
|
|
6376
|
+
* discover it by four dead sub-sessions. */
|
|
6377
|
+
if (multiagentEnabled) {
|
|
6378
|
+
const { hasUsableChildBrain } = await import('./tools/session_verbs.js');
|
|
6379
|
+
if (!(await hasUsableChildBrain()))
|
|
6380
|
+
multiagentEnabled = false;
|
|
6381
|
+
}
|
|
6248
6382
|
}
|
|
6249
6383
|
catch (_) { /* config failure -> stay OFF (safe default) */ }
|
|
6250
6384
|
/* alpha.59z.37 NAC-3 v3.x backend tools -- prefetch the
|
|
@@ -6413,7 +6547,7 @@ async function handleChat(req, res, ctx) {
|
|
|
6413
6547
|
* stable-first suffix lets a prefix cache extend through the unchanged
|
|
6414
6548
|
* dynamic lines instead of missing on the first per-turn byte. ~84% of
|
|
6415
6549
|
* this block was byte-identical turn-to-turn yet re-sent uncached. */
|
|
6416
|
-
systemDynamic: projectContextSection + sizingSection + urazukeSection + wiringSection + toolingSection + recentSessionsRecap + graphSection + snapshotSection + workflowSection + approvalPostureSection + toolStatusSection(),
|
|
6550
|
+
systemDynamic: projectContextSection + sizingSection + liveTasksSection + urazukeSection + wiringSection + toolingSection + recentSessionsRecap + graphSection + snapshotSection + workflowSection + approvalPostureSection + toolStatusSection(),
|
|
6417
6551
|
maxTokens: _maxTokensPerTurn,
|
|
6418
6552
|
/* Tope del turno en Plan, POR TURNO (Pablo 2026-10-04). Se leia solo al
|
|
6419
6553
|
* construir el cliente, asi que subir claude_cli_timeout_ms en el panel
|