@wrongstack/cli 1.0.27 → 1.0.29
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/data/providers.json +22 -0
- package/dist/{acp-M4565YUW.js → acp-QWCBMQSO.js} +2 -2
- package/dist/{chunk-RGFWGUAB.js → chunk-4UWCMBPG.js} +159 -3
- package/dist/{chunk-ENRYW73H.js → chunk-6A7URMWN.js} +79 -8
- package/dist/{chunk-HDMFKTT3.js → chunk-7IQWQCBH.js} +5 -2
- package/dist/{chunk-5JYDKG5B.js → chunk-BZHT5GPF.js} +6 -1
- package/dist/{chunk-HFZH2XJN.js → chunk-IFQ6NQPL.js} +4 -4
- package/dist/{chunk-N57IU5FG.js → chunk-KT34LWIS.js} +10 -9
- package/dist/{chunk-UZ2TMHNH.js → chunk-UKP7H2U4.js} +10 -2
- package/dist/{chunk-EPR42SWM.js → chunk-WRYZLEXP.js} +20 -1
- package/dist/{cli-context-C7RBSWHF.js → cli-context-6RONY47P.js} +18 -18
- package/dist/{cli-main-TQTH73ZK.js → cli-main-YS3HIOSD.js} +827 -313
- package/dist/{execution-3STBD2U7.js → execution-JEYF2L7O.js} +32 -24
- package/dist/fleet/host-explore-companion.d.ts +1 -1
- package/dist/fleet/host-memory-companion.d.ts +43 -0
- package/dist/fleet/host-subagent-factory.d.ts +1 -1
- package/dist/fleet/host.d.ts +1 -0
- package/dist/fleet/memory-companion-evidence.d.ts +12 -0
- package/dist/fleet/memory-companion-policy.d.ts +9 -0
- package/dist/goal-commands.d.ts +10 -0
- package/dist/{hq-44F4OQH2.js → hq-BNK67HOE.js} +3 -3
- package/dist/hq-publisher.d.ts +4 -1
- package/dist/hq-server/sage-sync-send.d.ts +5 -0
- package/dist/hq-server/server-lifecycle.d.ts +1 -1
- package/dist/hq-server/snapshot.d.ts +1 -1
- package/dist/{hq-server-UIB24LU6.js → hq-server-PCQACV7Y.js} +2 -2
- package/dist/hq-ttl-N4DAIAVX.js +7 -0
- package/dist/index.js +3 -3
- package/dist/{mailbox-serve-GNGXEQ2R.js → mailbox-serve-FW3JCCPK.js} +2 -2
- package/dist/{per-subcommand-help-QDAQASPZ.js → per-subcommand-help-MWQWFIAV.js} +2 -2
- package/dist/sage-FFKUOCQL.js +475 -0
- package/dist/sage-connect.d.ts +62 -0
- package/dist/sage-hq-sync.d.ts +8 -0
- package/dist/sage-sync-ZMTHB477.js +69 -0
- package/dist/services/run-git.d.ts +3 -1
- package/dist/{sessions-config-XHLXJ5C3.js → sessions-config-JGIZRNT6.js} +15 -4
- package/dist/{short-circuit-flags-5TNTJPQR.js → short-circuit-flags-5N2LPK4R.js} +3 -3
- package/dist/subcommands/handlers/helpers.d.ts +1 -1
- package/dist/subcommands/handlers/sage-sync.d.ts +4 -0
- package/dist/subcommands/handlers/sage.d.ts +5 -0
- package/dist/{subcommands-BHQYLDSD.js → subcommands-WX4GDMWB.js} +2 -2
- package/dist/{typesafe-U7YB2RRV.js → typesafe-WA5O3KVS.js} +10 -2
- package/dist/{version-help-XJJQ7YSH.js → version-help-HN32QYQN.js} +2 -2
- package/dist/{webui-server-GCXIO3JY.js → webui-server-EXJWLB3X.js} +10 -8
- package/package.json +30 -29
- package/dist/hq-ttl-VJR65OBJ.js +0 -7
package/data/providers.json
CHANGED
|
@@ -4,6 +4,28 @@
|
|
|
4
4
|
"name": "OpenAI Codex (ChatGPT sign-in)",
|
|
5
5
|
"doc": "https://developers.openai.com/codex/models",
|
|
6
6
|
"models": {
|
|
7
|
+
"gpt-6.1-sol": {
|
|
8
|
+
"id": "gpt-6.1-sol",
|
|
9
|
+
"name": "GPT-6.1 Sol",
|
|
10
|
+
"description": "Latest workhorse model for coding and everyday work.",
|
|
11
|
+
"reasoning": true,
|
|
12
|
+
"reasoningConfig": {
|
|
13
|
+
"default": "enabled",
|
|
14
|
+
"disableSupported": false,
|
|
15
|
+
"effortSupported": true,
|
|
16
|
+
"effortLevels": ["low", "medium", "high", "xhigh", "max"],
|
|
17
|
+
"preserveThinking": "unsupported"
|
|
18
|
+
},
|
|
19
|
+
"tool_call": true,
|
|
20
|
+
"modalities": {
|
|
21
|
+
"input": ["text", "image"],
|
|
22
|
+
"output": ["text"]
|
|
23
|
+
},
|
|
24
|
+
"limit": {
|
|
25
|
+
"context": 872000,
|
|
26
|
+
"output": 128000
|
|
27
|
+
}
|
|
28
|
+
},
|
|
7
29
|
"gpt-6-astra": {
|
|
8
30
|
"id": "gpt-6-astra",
|
|
9
31
|
"name": "GPT-6 Astra",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-NRXWOMK7.js";
|
|
11
11
|
import {
|
|
12
12
|
startCliHqConnection
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-4UWCMBPG.js";
|
|
14
14
|
import "./chunk-SDJCLEK6.js";
|
|
15
15
|
import "./chunk-F5DCFAKI.js";
|
|
16
16
|
import "./chunk-SIGUWXAA.js";
|
|
@@ -1192,4 +1192,4 @@ ${renderAcpBenchText(result)}
|
|
|
1192
1192
|
export {
|
|
1193
1193
|
acpCmd
|
|
1194
1194
|
};
|
|
1195
|
-
//# sourceMappingURL=acp-
|
|
1195
|
+
//# sourceMappingURL=acp-QWCBMQSO.js.map
|
|
@@ -426,6 +426,146 @@ async function writeState(projectRoot, state) {
|
|
|
426
426
|
await writeKanbanMetadata(projectRoot, SYNC_STATE_KEY, JSON.stringify(state));
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
+
// src/sage-hq-sync.ts
|
|
430
|
+
import {
|
|
431
|
+
chunkHqSageRecords,
|
|
432
|
+
compareHqSageRecords,
|
|
433
|
+
isHqSageRecord,
|
|
434
|
+
MAX_HQ_SAGE_RECORD_BYTES
|
|
435
|
+
} from "@wrongstack/core/hq";
|
|
436
|
+
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
437
|
+
import { SageProjectServerConnection } from "@wrongstack/sage";
|
|
438
|
+
function createSageHqSync(projectRoot, publisher, directory) {
|
|
439
|
+
const connection = new SageProjectServerConnection(projectRoot, directory);
|
|
440
|
+
const acknowledged = /* @__PURE__ */ new Map();
|
|
441
|
+
const sent = /* @__PURE__ */ new Map();
|
|
442
|
+
const warned = /* @__PURE__ */ new Map();
|
|
443
|
+
const remote = /* @__PURE__ */ new Map();
|
|
444
|
+
const controller = new AbortController();
|
|
445
|
+
const callOptions = { meta: { clientId: "hq-sage-sync" }, signal: controller.signal };
|
|
446
|
+
let stopped = false;
|
|
447
|
+
let running;
|
|
448
|
+
let lastFailure;
|
|
449
|
+
let lastScanVersion;
|
|
450
|
+
let generation = 0;
|
|
451
|
+
const version = (r) => `${r.revision}:${r.changeId}`;
|
|
452
|
+
const synchronize = async () => {
|
|
453
|
+
const startedGeneration = generation;
|
|
454
|
+
while (remote.size && !stopped && startedGeneration === generation) {
|
|
455
|
+
const batch = chunkHqSageRecords(publisher.project.projectId, remote.values()).next();
|
|
456
|
+
if (batch.done) break;
|
|
457
|
+
const records = batch.value.records;
|
|
458
|
+
for (const r of records) remote.delete(r.id);
|
|
459
|
+
try {
|
|
460
|
+
await connection.call("applyHqSync", { records }, callOptions);
|
|
461
|
+
for (const r of records) {
|
|
462
|
+
if (startedGeneration !== generation) break;
|
|
463
|
+
acknowledged.set(r.id, version(r));
|
|
464
|
+
if (sent.get(r.id) === version(r)) sent.delete(r.id);
|
|
465
|
+
}
|
|
466
|
+
} catch (error) {
|
|
467
|
+
if (stopped || startedGeneration !== generation) return;
|
|
468
|
+
for (const r of records) {
|
|
469
|
+
const pending = remote.get(r.id);
|
|
470
|
+
if (!pending || compareHqSageRecords(r, pending) > 0) remote.set(r.id, r);
|
|
471
|
+
}
|
|
472
|
+
throw error;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const scanVersion = await connection.call("getHqSyncVersion", {}, callOptions);
|
|
476
|
+
if (stopped || startedGeneration !== generation || !publisher.connected) return;
|
|
477
|
+
if (scanVersion === lastScanVersion && sent.size === 0) return;
|
|
478
|
+
let after = "";
|
|
479
|
+
while (!stopped && publisher.connected) {
|
|
480
|
+
const page = await connection.call("listHqSync", { after }, callOptions);
|
|
481
|
+
if (stopped || startedGeneration !== generation || !publisher.connected) return;
|
|
482
|
+
if (!page.length) {
|
|
483
|
+
lastScanVersion = scanVersion;
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const outgoing = page.filter((r) => {
|
|
487
|
+
if (acknowledged.get(r.id) === version(r)) {
|
|
488
|
+
sent.delete(r.id);
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
if (isHqSageRecord(r)) {
|
|
492
|
+
warned.delete(r.id);
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
if (warned.get(r.id) !== version(r)) {
|
|
496
|
+
process.emitWarning(
|
|
497
|
+
`SAGE memory ${r.id} cannot sync: invalid record or exceeds ${MAX_HQ_SAGE_RECORD_BYTES} bytes. Other memories will continue syncing.`,
|
|
498
|
+
{ code: "WRONGSTACK_HQ_SAGE_RECORD_REJECTED" }
|
|
499
|
+
);
|
|
500
|
+
warned.set(r.id, version(r));
|
|
501
|
+
}
|
|
502
|
+
return false;
|
|
503
|
+
});
|
|
504
|
+
for (const payload of chunkHqSageRecords(publisher.project.projectId, outgoing)) {
|
|
505
|
+
for (const r of payload.records) sent.set(r.id, version(r));
|
|
506
|
+
publisher.publishEvent({
|
|
507
|
+
type: "sage.snapshot",
|
|
508
|
+
payload,
|
|
509
|
+
maxSummaryLength: MAX_HQ_SAGE_RECORD_BYTES
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
after = page[page.length - 1].id;
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
const refresh = () => {
|
|
516
|
+
if (stopped || !publisher.connected) return Promise.resolve();
|
|
517
|
+
if (running) return running;
|
|
518
|
+
running = synchronize().then(() => {
|
|
519
|
+
lastFailure = void 0;
|
|
520
|
+
}).catch((error) => {
|
|
521
|
+
const message = toErrorMessage(error);
|
|
522
|
+
if (!stopped && lastFailure !== message) {
|
|
523
|
+
process.emitWarning(`SAGE HQ sync will retry: ${message}`, {
|
|
524
|
+
code: "WRONGSTACK_HQ_SAGE_SYNC_FAILED"
|
|
525
|
+
});
|
|
526
|
+
lastFailure = message;
|
|
527
|
+
}
|
|
528
|
+
}).finally(() => {
|
|
529
|
+
running = void 0;
|
|
530
|
+
});
|
|
531
|
+
return running;
|
|
532
|
+
};
|
|
533
|
+
const unsubscribe = publisher.onConnected(() => {
|
|
534
|
+
generation++;
|
|
535
|
+
remote.clear();
|
|
536
|
+
acknowledged.clear();
|
|
537
|
+
sent.clear();
|
|
538
|
+
lastScanVersion = void 0;
|
|
539
|
+
void refresh();
|
|
540
|
+
});
|
|
541
|
+
const timer = setInterval(() => void refresh(), 3e3);
|
|
542
|
+
timer.unref?.();
|
|
543
|
+
void refresh();
|
|
544
|
+
return {
|
|
545
|
+
async handleRemote(snapshot) {
|
|
546
|
+
if (stopped || snapshot.projectId !== publisher.project.projectId) return;
|
|
547
|
+
for (const r of snapshot.records) {
|
|
548
|
+
const pending = remote.get(r.id);
|
|
549
|
+
if (!pending || compareHqSageRecords(r, pending) > 0) remote.set(r.id, r);
|
|
550
|
+
}
|
|
551
|
+
await refresh();
|
|
552
|
+
},
|
|
553
|
+
refresh,
|
|
554
|
+
stop() {
|
|
555
|
+
stopped = true;
|
|
556
|
+
controller.abort();
|
|
557
|
+
clearInterval(timer);
|
|
558
|
+
unsubscribe();
|
|
559
|
+
remote.clear();
|
|
560
|
+
acknowledged.clear();
|
|
561
|
+
sent.clear();
|
|
562
|
+
warned.clear();
|
|
563
|
+
connection.close();
|
|
564
|
+
void running?.finally(() => connection.close());
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
429
569
|
// src/hq-publisher.ts
|
|
430
570
|
var HQ_DISCOVERY_CONNECTION_KEY = "<discover>";
|
|
431
571
|
function nodeWsSocketFactory(url) {
|
|
@@ -450,15 +590,20 @@ function resolvedHqConnectionKey(options) {
|
|
|
450
590
|
const endpoint = config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${config.url}
|
|
451
591
|
${config.token ?? ""}`;
|
|
452
592
|
return `${endpoint}
|
|
453
|
-
raw=${String(config.rawContent)}
|
|
593
|
+
raw=${String(config.rawContent)}
|
|
594
|
+
sage=${options.appConfig?.Sage?.storage?.directory ?? ""}`;
|
|
454
595
|
}
|
|
455
596
|
function startCliHqConnection(options) {
|
|
456
597
|
const shouldOwnKanbanSync = options.ownKanbanSync !== false && options.onKanbanSnapshot === void 0;
|
|
457
598
|
let kanbanSync;
|
|
599
|
+
let sageSync;
|
|
600
|
+
const shouldOwnSageSync = (options.ownSageSync ?? options.ownKanbanSync !== false) && options.onSageSnapshot === void 0;
|
|
458
601
|
const publisherOptions = shouldOwnKanbanSync ? {
|
|
459
602
|
...options,
|
|
460
603
|
onKanbanSnapshot: (snapshot) => kanbanSync?.handleRemote(snapshot)
|
|
461
|
-
} : options;
|
|
604
|
+
} : { ...options };
|
|
605
|
+
if (shouldOwnSageSync)
|
|
606
|
+
publisherOptions.onSageSnapshot = (snapshot) => sageSync?.handleRemote(snapshot);
|
|
462
607
|
let publisher;
|
|
463
608
|
let publisherKey;
|
|
464
609
|
let timer;
|
|
@@ -467,6 +612,8 @@ function startCliHqConnection(options) {
|
|
|
467
612
|
if (publisher === void 0) return;
|
|
468
613
|
kanbanSync?.stop();
|
|
469
614
|
kanbanSync = void 0;
|
|
615
|
+
sageSync?.stop();
|
|
616
|
+
sageSync = void 0;
|
|
470
617
|
publisher.close();
|
|
471
618
|
publisher = void 0;
|
|
472
619
|
publisherKey = void 0;
|
|
@@ -484,6 +631,8 @@ function startCliHqConnection(options) {
|
|
|
484
631
|
`)) publisher.refreshEndpoint();
|
|
485
632
|
return;
|
|
486
633
|
}
|
|
634
|
+
sageSync?.stop();
|
|
635
|
+
sageSync = void 0;
|
|
487
636
|
publisher?.close();
|
|
488
637
|
publisher = void 0;
|
|
489
638
|
publisherKey = void 0;
|
|
@@ -495,6 +644,12 @@ function startCliHqConnection(options) {
|
|
|
495
644
|
kanbanSync?.stop();
|
|
496
645
|
kanbanSync = createKanbanHqSync(options.projectRoot, next.project.projectId);
|
|
497
646
|
}
|
|
647
|
+
if (shouldOwnSageSync)
|
|
648
|
+
sageSync = createSageHqSync(
|
|
649
|
+
options.projectRoot,
|
|
650
|
+
next,
|
|
651
|
+
current.appConfig?.Sage?.storage?.directory
|
|
652
|
+
);
|
|
498
653
|
next.connect();
|
|
499
654
|
if (kanbanSync !== void 0) {
|
|
500
655
|
kanbanSync.attachPublisher(next).catch((error) => {
|
|
@@ -520,6 +675,7 @@ function startCliHqConnection(options) {
|
|
|
520
675
|
timer = void 0;
|
|
521
676
|
}
|
|
522
677
|
kanbanSync?.stop();
|
|
678
|
+
sageSync?.stop();
|
|
523
679
|
publisher?.close();
|
|
524
680
|
publisher = void 0;
|
|
525
681
|
publisherKey = void 0;
|
|
@@ -530,4 +686,4 @@ function startCliHqConnection(options) {
|
|
|
530
686
|
export {
|
|
531
687
|
startCliHqConnection
|
|
532
688
|
};
|
|
533
|
-
//# sourceMappingURL=chunk-
|
|
689
|
+
//# sourceMappingURL=chunk-4UWCMBPG.js.map
|
|
@@ -1689,7 +1689,7 @@ import { WebSocket } from "ws";
|
|
|
1689
1689
|
var HQ_SNAPSHOT_BROADCAST_DEBOUNCE_MS = 100;
|
|
1690
1690
|
var HQ_SNAPSHOT_PERSIST_MIN_INTERVAL_MS = 3e3;
|
|
1691
1691
|
var HQ_BROWSER_MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
|
|
1692
|
-
function sendGuarded(ws, data) {
|
|
1692
|
+
function sendGuarded(ws, data, callback) {
|
|
1693
1693
|
if (ws.readyState !== WebSocket.OPEN) return false;
|
|
1694
1694
|
const buffered = Number.isFinite(ws.bufferedAmount) ? ws.bufferedAmount : 0;
|
|
1695
1695
|
if (buffered + Buffer.byteLength(data, "utf8") > HQ_BROWSER_MAX_BUFFERED_BYTES) {
|
|
@@ -1704,7 +1704,8 @@ function sendGuarded(ws, data) {
|
|
|
1704
1704
|
return false;
|
|
1705
1705
|
}
|
|
1706
1706
|
try {
|
|
1707
|
-
ws.send(data);
|
|
1707
|
+
if (callback) ws.send(data, callback);
|
|
1708
|
+
else ws.send(data);
|
|
1708
1709
|
return true;
|
|
1709
1710
|
} catch {
|
|
1710
1711
|
return false;
|
|
@@ -3770,7 +3771,8 @@ function createHqServerShutdown(params) {
|
|
|
3770
3771
|
params.persistence.eventLog.drain(),
|
|
3771
3772
|
params.persistence.snapshotStore.drain(),
|
|
3772
3773
|
params.persistence.timeseries.drain(),
|
|
3773
|
-
params.persistence.kanban.drain()
|
|
3774
|
+
params.persistence.kanban.drain(),
|
|
3775
|
+
params.persistence.sage?.drain()
|
|
3774
3776
|
]).then(() => clearHqRuntimeMarker(params.dataDir, params.hqUrl)).catch(() => void 0).finally(() => res());
|
|
3775
3777
|
});
|
|
3776
3778
|
});
|
|
@@ -3849,16 +3851,56 @@ import {
|
|
|
3849
3851
|
tightenHqRedactionPolicy as tightenHqRedactionPolicy2,
|
|
3850
3852
|
tokenHasCapability as tokenHasCapability3
|
|
3851
3853
|
} from "@wrongstack/core/hq";
|
|
3854
|
+
import { toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
|
|
3852
3855
|
import { WebSocket as WebSocket3 } from "ws";
|
|
3853
3856
|
|
|
3857
|
+
// src/hq-server/sage-sync-send.ts
|
|
3858
|
+
import { chunkHqSageRecords } from "@wrongstack/core/hq";
|
|
3859
|
+
async function sendSageSnapshot(ws, snapshot) {
|
|
3860
|
+
for (const part of chunkHqSageRecords(snapshot.projectId, snapshot.records)) {
|
|
3861
|
+
const delivered = await new Promise((resolve) => {
|
|
3862
|
+
let settled = false;
|
|
3863
|
+
const finish = (ok) => {
|
|
3864
|
+
if (settled) return;
|
|
3865
|
+
settled = true;
|
|
3866
|
+
clearTimeout(timer);
|
|
3867
|
+
ws.removeListener("close", onClose);
|
|
3868
|
+
resolve(ok);
|
|
3869
|
+
};
|
|
3870
|
+
const onClose = () => finish(false);
|
|
3871
|
+
const timer = setTimeout(() => {
|
|
3872
|
+
finish(false);
|
|
3873
|
+
try {
|
|
3874
|
+
ws.terminate();
|
|
3875
|
+
} catch {
|
|
3876
|
+
}
|
|
3877
|
+
}, 1e4);
|
|
3878
|
+
timer.unref?.();
|
|
3879
|
+
ws.once("close", onClose);
|
|
3880
|
+
const accepted = sendGuarded(
|
|
3881
|
+
ws,
|
|
3882
|
+
JSON.stringify({ type: "hq.sage_snapshot", payload: part }),
|
|
3883
|
+
(error) => finish(!error)
|
|
3884
|
+
);
|
|
3885
|
+
if (!accepted) finish(false);
|
|
3886
|
+
});
|
|
3887
|
+
if (!delivered) return false;
|
|
3888
|
+
}
|
|
3889
|
+
return true;
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3854
3892
|
// src/hq-server/ws-client-events.ts
|
|
3855
3893
|
import {
|
|
3894
|
+
chunkHqSageRecords as chunkHqSageRecords2,
|
|
3856
3895
|
HQ_TRANSCRIPT_TEXT_CAP,
|
|
3896
|
+
isHqSageSnapshotPayload,
|
|
3897
|
+
MAX_HQ_SAGE_RECORD_BYTES,
|
|
3857
3898
|
parseHqEventPayload,
|
|
3858
3899
|
redactHqEvent,
|
|
3859
3900
|
tightenHqRedactionPolicy,
|
|
3860
3901
|
tokenHasCapability as tokenHasCapability2
|
|
3861
3902
|
} from "@wrongstack/core/hq";
|
|
3903
|
+
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
3862
3904
|
function fanoutKanbanDelta(message, clients, _browsers, projectId) {
|
|
3863
3905
|
let clientsNotified = 0;
|
|
3864
3906
|
for (const peer of clients.values()) {
|
|
@@ -3908,12 +3950,33 @@ function handleIncomingClientEvent(ws, incomingEvent, clients, browsers, auth, s
|
|
|
3908
3950
|
// Chat-transcript events carry full turns — the generic 500-char
|
|
3909
3951
|
// summary cap would truncate them a second time after the
|
|
3910
3952
|
// publisher already applied the transcript cap.
|
|
3911
|
-
...incomingEvent.type === "session.transcript" || incomingEvent.type === "agent.message" ? { maxSummaryLength: HQ_TRANSCRIPT_TEXT_CAP } : {}
|
|
3953
|
+
...incomingEvent.type === "sage.snapshot" ? { maxSummaryLength: MAX_HQ_SAGE_RECORD_BYTES } : incomingEvent.type === "session.transcript" || incomingEvent.type === "agent.message" ? { maxSummaryLength: HQ_TRANSCRIPT_TEXT_CAP } : {}
|
|
3912
3954
|
}
|
|
3913
3955
|
).value;
|
|
3914
3956
|
if (event.type === "client.heartbeat") {
|
|
3915
3957
|
return;
|
|
3916
3958
|
}
|
|
3959
|
+
if (event.type === "sage.snapshot") {
|
|
3960
|
+
const payload = event.payload;
|
|
3961
|
+
if (!isHqSageSnapshotPayload(payload) || payload.projectId !== client.projectId || !persistence?.sage)
|
|
3962
|
+
return;
|
|
3963
|
+
void persistence.sage.merge(payload).then((merged) => {
|
|
3964
|
+
for (const part of chunkHqSageRecords2(client.projectId, merged.records)) {
|
|
3965
|
+
fanoutKanbanDelta(
|
|
3966
|
+
JSON.stringify({ type: "hq.sage_snapshot", payload: part }),
|
|
3967
|
+
clients,
|
|
3968
|
+
browsers,
|
|
3969
|
+
client.projectId
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
}).catch(
|
|
3973
|
+
(error) => process.stderr.write(
|
|
3974
|
+
`${JSON.stringify({ level: "warn", event: "hq.sage_sync_failed", projectId: client.projectId, message: toErrorMessage(error) })}
|
|
3975
|
+
`
|
|
3976
|
+
)
|
|
3977
|
+
);
|
|
3978
|
+
return;
|
|
3979
|
+
}
|
|
3917
3980
|
if (event.type === "kanban.snapshot") {
|
|
3918
3981
|
const payload = event.payload;
|
|
3919
3982
|
if (payload.projectId !== client.projectId || persistence === void 0) return;
|
|
@@ -3934,7 +3997,7 @@ function handleIncomingClientEvent(ws, incomingEvent, clients, browsers, auth, s
|
|
|
3934
3997
|
JSON.stringify({
|
|
3935
3998
|
level: "warn",
|
|
3936
3999
|
event: "hq.kanban_merge_failed",
|
|
3937
|
-
message:
|
|
4000
|
+
message: toErrorMessage(error),
|
|
3938
4001
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3939
4002
|
})
|
|
3940
4003
|
);
|
|
@@ -4343,7 +4406,7 @@ function handleBrowser(ws, snapshotBroadcaster, browsers, eventLog) {
|
|
|
4343
4406
|
JSON.stringify({
|
|
4344
4407
|
level: "warn",
|
|
4345
4408
|
event: "hq.browser_socket_error",
|
|
4346
|
-
message:
|
|
4409
|
+
message: toErrorMessage2(err),
|
|
4347
4410
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4348
4411
|
})
|
|
4349
4412
|
);
|
|
@@ -4424,7 +4487,7 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
4424
4487
|
JSON.stringify({
|
|
4425
4488
|
level: "warn",
|
|
4426
4489
|
event: "hq.client_socket_error",
|
|
4427
|
-
message:
|
|
4490
|
+
message: toErrorMessage2(err),
|
|
4428
4491
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4429
4492
|
})
|
|
4430
4493
|
);
|
|
@@ -4525,6 +4588,14 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
4525
4588
|
sendGuarded(ws, JSON.stringify({ type: "hq.kanban_snapshot", payload: p }));
|
|
4526
4589
|
}).catch(() => void 0);
|
|
4527
4590
|
}
|
|
4591
|
+
if (persistence?.sage !== void 0) {
|
|
4592
|
+
void persistence.sage.load(client.projectId).then((snapshot) => sendSageSnapshot(ws, snapshot)).catch(
|
|
4593
|
+
(error) => process.stderr.write(
|
|
4594
|
+
`${JSON.stringify({ level: "warn", event: "hq.sage_restore_failed", projectId: client.projectId, message: toErrorMessage2(error) })}
|
|
4595
|
+
`
|
|
4596
|
+
)
|
|
4597
|
+
);
|
|
4598
|
+
}
|
|
4528
4599
|
const event = redactHqEvent2(
|
|
4529
4600
|
{
|
|
4530
4601
|
id: randomUUID5(),
|
|
@@ -5296,4 +5367,4 @@ export {
|
|
|
5296
5367
|
startHqServer,
|
|
5297
5368
|
HqInsecureExposureError2 as HqInsecureExposureError
|
|
5298
5369
|
};
|
|
5299
|
-
//# sourceMappingURL=chunk-
|
|
5370
|
+
//# sourceMappingURL=chunk-6A7URMWN.js.map
|
|
@@ -112,17 +112,20 @@ function normalizeTuiThinkingWord(value) {
|
|
|
112
112
|
// src/services/run-git.ts
|
|
113
113
|
import { spawn } from "node:child_process";
|
|
114
114
|
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
115
|
-
async function runGit(args, cwd) {
|
|
115
|
+
async function runGit(args, cwd, env) {
|
|
116
116
|
try {
|
|
117
117
|
return await new Promise((resolve, reject) => {
|
|
118
118
|
const child = spawn("git", args, {
|
|
119
119
|
cwd,
|
|
120
|
+
...env ? { env: { ...process.env, ...env } } : {},
|
|
120
121
|
stdio: ["ignore", "pipe", "pipe"],
|
|
121
122
|
signal: AbortSignal.timeout(3e4),
|
|
122
123
|
windowsHide: true
|
|
123
124
|
});
|
|
124
125
|
let stdout = "";
|
|
125
126
|
let stderr = "";
|
|
127
|
+
child.stdout?.setEncoding("utf8");
|
|
128
|
+
child.stderr?.setEncoding("utf8");
|
|
126
129
|
child.stdout?.on("data", (d) => {
|
|
127
130
|
stdout += d;
|
|
128
131
|
});
|
|
@@ -154,4 +157,4 @@ export {
|
|
|
154
157
|
normalizeTuiThinkingWord,
|
|
155
158
|
runGit
|
|
156
159
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
160
|
+
//# sourceMappingURL=chunk-7IQWQCBH.js.map
|
|
@@ -56,6 +56,11 @@ var helpCmd = async (_args, deps) => {
|
|
|
56
56
|
["wstack config-export | config-import", "Move behaviour settings via ./wstack-config.json"],
|
|
57
57
|
["wstack mcp", "MCP servers: list, add, remove, serve"],
|
|
58
58
|
["wstack import-claude-code", "Import MCP servers from Claude Code (preview; --apply)"],
|
|
59
|
+
[
|
|
60
|
+
"wstack sage connect",
|
|
61
|
+
"SAGE memory in Claude Code, Codex, Cursor, Antigravity (MCP + skill)"
|
|
62
|
+
],
|
|
63
|
+
["wstack sage sync", "Keep project SAGE memory synchronized through HQ"],
|
|
59
64
|
["wstack plugin", "Plugins: list, install, enable, disable, remove"],
|
|
60
65
|
["wstack tools | skills", "List registered tools / discovered skills"],
|
|
61
66
|
["wstack typesafe", "TypeSafe account: status, login, test"],
|
|
@@ -151,4 +156,4 @@ export {
|
|
|
151
156
|
versionCmd,
|
|
152
157
|
helpCmd
|
|
153
158
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-BZHT5GPF.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
helpCmd,
|
|
3
3
|
versionCmd
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BZHT5GPF.js";
|
|
5
5
|
import {
|
|
6
6
|
parseArgs
|
|
7
7
|
} from "./chunk-Q4INH2DG.js";
|
|
@@ -22,11 +22,11 @@ async function handleHelpVersionShortCircuit(argv) {
|
|
|
22
22
|
}
|
|
23
23
|
if (earlyFlags["help"] === true) {
|
|
24
24
|
if (positional.length > 0) {
|
|
25
|
-
const { subcommandNames } = await import("./subcommands-
|
|
25
|
+
const { subcommandNames } = await import("./subcommands-WX4GDMWB.js");
|
|
26
26
|
if (subcommandNames.includes(positional[0])) {
|
|
27
27
|
const first = positional[0];
|
|
28
28
|
const deep = positional[1];
|
|
29
|
-
const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-
|
|
29
|
+
const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-MWQWFIAV.js");
|
|
30
30
|
if (deep && renderDeepHelp(`${first}:${deep}`, stubRenderer)) {
|
|
31
31
|
return 0;
|
|
32
32
|
}
|
|
@@ -43,4 +43,4 @@ async function handleHelpVersionShortCircuit(argv) {
|
|
|
43
43
|
export {
|
|
44
44
|
handleHelpVersionShortCircuit
|
|
45
45
|
};
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-IFQ6NQPL.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
// src/subcommands/index.ts
|
|
3
3
|
var loaders = {
|
|
4
|
-
acp: async () => (await import("./acp-
|
|
4
|
+
acp: async () => (await import("./acp-QWCBMQSO.js")).acpCmd,
|
|
5
5
|
init: async () => (await import("./init-DRMMFG2G.js")).initCmd,
|
|
6
6
|
auth: async () => (await import("./auth-TE55JF4Z.js")).authCmd,
|
|
7
7
|
update: async () => (await import("./update-TDZX4IL2.js")).updateCmd,
|
|
8
8
|
remote: async () => (await import("./remote-GB5VXCCT.js")).remoteCmd,
|
|
9
|
-
sessions: async () => (await import("./sessions-config-
|
|
10
|
-
config: async () => (await import("./sessions-config-
|
|
9
|
+
sessions: async () => (await import("./sessions-config-JGIZRNT6.js")).sessionsCmd,
|
|
10
|
+
config: async () => (await import("./sessions-config-JGIZRNT6.js")).configCmd,
|
|
11
11
|
"config-export": async () => (await import("./config-transfer-RUWLDCNK.js")).configExportCmd,
|
|
12
12
|
"config-import": async () => (await import("./config-transfer-RUWLDCNK.js")).configImportCmd,
|
|
13
13
|
rewind: async () => (await import("./rewind-JA3ZLCNM.js")).rewindCmd,
|
|
@@ -16,7 +16,7 @@ var loaders = {
|
|
|
16
16
|
tools: async () => (await import("./tools-skills-GH24UCBY.js")).toolsCmd,
|
|
17
17
|
skills: async () => (await import("./tools-skills-GH24UCBY.js")).skillsCmd,
|
|
18
18
|
"skill-suggest": async () => (await import("./skill-suggest-L2EVWB6R.js")).skillSuggestCmd,
|
|
19
|
-
typesafe: async () => (await import("./typesafe-
|
|
19
|
+
typesafe: async () => (await import("./typesafe-WA5O3KVS.js")).typesafeCmd,
|
|
20
20
|
providers: async () => (await import("./providers-models-5Z2PJTEW.js")).providersCmd,
|
|
21
21
|
models: async () => (await import("./providers-models-5Z2PJTEW.js")).modelsCmd,
|
|
22
22
|
mcp: async () => (await import("./mcp-LBS45HWZ.js")).mcpCmd,
|
|
@@ -27,17 +27,18 @@ var loaders = {
|
|
|
27
27
|
"proxy-status": async () => (await import("./diag-doctor-BIZAFIAT.js")).proxyCmd,
|
|
28
28
|
export: async () => (await import("./export-VVRIOWFV.js")).exportCmd,
|
|
29
29
|
usage: async () => (await import("./plugin-usage-CIGOOTX3.js")).usageCmd,
|
|
30
|
-
version: async () => (await import("./version-help-
|
|
31
|
-
help: async () => (await import("./version-help-
|
|
30
|
+
version: async () => (await import("./version-help-HN32QYQN.js")).versionCmd,
|
|
31
|
+
help: async () => (await import("./version-help-HN32QYQN.js")).helpCmd,
|
|
32
32
|
projects: async () => (await import("./projects-T4CZCA25.js")).projectsCmd,
|
|
33
33
|
modeldiag: async () => (await import("./modeldiag-W7XAE625.js")).modeldiagCmd,
|
|
34
34
|
quick: async () => (await import("./quick-CNB4Z3HS.js")).quickCmd,
|
|
35
35
|
bench: async () => (await import("./bench-GTLPM22B.js")).benchCmd,
|
|
36
36
|
chronicle: async () => (await import("./chronicle-UTFETHP6.js")).chronicleCmd,
|
|
37
|
-
hq: async () => (await import("./hq-
|
|
38
|
-
mailbox: async () => (await import("./mailbox-serve-
|
|
37
|
+
hq: async () => (await import("./hq-BNK67HOE.js")).hqCmd,
|
|
38
|
+
mailbox: async () => (await import("./mailbox-serve-FW3JCCPK.js")).mailboxServeCmd,
|
|
39
39
|
permissions: async () => (await import("./permissions-PL27UHYD.js")).permissionsCmd,
|
|
40
40
|
project: async () => (await import("./project-AOQI5XTK.js")).projectCmd,
|
|
41
|
+
sage: async () => (await import("./sage-FFKUOCQL.js")).sageCmd,
|
|
41
42
|
governance: async () => (await import("./governance-RYSHV675.js")).governanceCmd,
|
|
42
43
|
"import-claude-code": async () => (await import("./import-claude-code-AYG24RG2.js")).importClaudeCodeCmd
|
|
43
44
|
};
|
|
@@ -55,4 +56,4 @@ export {
|
|
|
55
56
|
subcommands,
|
|
56
57
|
subcommandNames
|
|
57
58
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
59
|
+
//# sourceMappingURL=chunk-KT34LWIS.js.map
|
|
@@ -8,6 +8,7 @@ var TTL_UNIT_MS = {
|
|
|
8
8
|
d: 864e5,
|
|
9
9
|
w: 6048e5
|
|
10
10
|
};
|
|
11
|
+
var MAX_SAFE_TTL_MS = 864e13;
|
|
11
12
|
function parseTokenTtlValue(raw) {
|
|
12
13
|
const trimmed = raw.trim();
|
|
13
14
|
if (trimmed.length === 0) {
|
|
@@ -18,6 +19,9 @@ function parseTokenTtlValue(raw) {
|
|
|
18
19
|
if (!Number.isFinite(ms) || ms <= 0) {
|
|
19
20
|
return { error: `TTL value must be positive (got ${raw})` };
|
|
20
21
|
}
|
|
22
|
+
if (!Number.isSafeInteger(ms) || ms > MAX_SAFE_TTL_MS) {
|
|
23
|
+
return { error: `TTL value exceeds maximum safe duration (got ${raw})` };
|
|
24
|
+
}
|
|
21
25
|
return { value: ms };
|
|
22
26
|
}
|
|
23
27
|
const match = /^(?<value>\d+)(?<unit>ms|s|m|h|d|w)$/i.exec(trimmed);
|
|
@@ -28,7 +32,11 @@ function parseTokenTtlValue(raw) {
|
|
|
28
32
|
if (!Number.isFinite(value) || value <= 0 || multiplier === void 0) {
|
|
29
33
|
return { error: `TTL value must be positive with a valid unit (got ${raw})` };
|
|
30
34
|
}
|
|
31
|
-
|
|
35
|
+
const totalMs = value * multiplier;
|
|
36
|
+
if (!Number.isSafeInteger(value) || !Number.isSafeInteger(totalMs) || totalMs > MAX_SAFE_TTL_MS) {
|
|
37
|
+
return { error: `TTL value exceeds maximum safe duration (got ${raw})` };
|
|
38
|
+
}
|
|
39
|
+
return { value: totalMs };
|
|
32
40
|
}
|
|
33
41
|
return {
|
|
34
42
|
error: `TTL must be a positive integer (milliseconds) or <number><unit> where unit is one of ms, s, m, h, d, w (got ${raw})`
|
|
@@ -38,4 +46,4 @@ function parseTokenTtlValue(raw) {
|
|
|
38
46
|
export {
|
|
39
47
|
parseTokenTtlValue
|
|
40
48
|
};
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
49
|
+
//# sourceMappingURL=chunk-UKP7H2U4.js.map
|
|
@@ -1142,6 +1142,25 @@ var helpTable = {
|
|
|
1142
1142
|
],
|
|
1143
1143
|
seeAlso: "wstack mcp list; --mcp-config (one-off servers without importing)"
|
|
1144
1144
|
},
|
|
1145
|
+
sage: {
|
|
1146
|
+
name: "sage",
|
|
1147
|
+
title: "wstack sage \u2014 this project's SAGE memory in other coding agents",
|
|
1148
|
+
description: "Wire SAGE memory into Claude Code, Codex, Cursor or Antigravity over MCP: writes the MCP server entry plus a skill/rule telling the agent when to recall and how to propose. The server attaches to the SAGE daemon while wstack is open in this project and never starts one. Tools are read-only plus memory_candidates (list/propose); a proposal becomes memory only through WrongStack review. Search is lexical: semantic recall runs inside a WrongStack host.",
|
|
1149
|
+
usage: "wstack sage connect <claude-code|codex|cursor|antigravity|all|print> [--dry-run]",
|
|
1150
|
+
subcommands: [
|
|
1151
|
+
{ name: "connect <client|all>", description: "Write the MCP entry and skill for a client." },
|
|
1152
|
+
{ name: "connect print", description: "Print JSON/TOML config for any other MCP client." },
|
|
1153
|
+
{ name: "disconnect <client|all>", description: "Remove what connect wrote." },
|
|
1154
|
+
{ name: "mcp [--origin <name>]", description: "The stdio MCP server clients run." },
|
|
1155
|
+
{
|
|
1156
|
+
name: "sync [--restart-service]",
|
|
1157
|
+
description: "Run project memory sync with HQ; optionally restart this project\u2019s SAGE owner."
|
|
1158
|
+
},
|
|
1159
|
+
{ name: "--dry-run", description: "Show the file changes without writing." },
|
|
1160
|
+
{ name: "--command <path>", description: "Executable to launch instead of wstack." }
|
|
1161
|
+
],
|
|
1162
|
+
seeAlso: "wstack mcp serve (all WrongStack tools over MCP)"
|
|
1163
|
+
},
|
|
1145
1164
|
// -- Chronicle ──────────────────────────────────────────────────────
|
|
1146
1165
|
chronicle: {
|
|
1147
1166
|
name: "chronicle",
|
|
@@ -1243,4 +1262,4 @@ export {
|
|
|
1243
1262
|
subcommandsWithFocusedHelp,
|
|
1244
1263
|
renderGenericHelp
|
|
1245
1264
|
};
|
|
1246
|
-
//# sourceMappingURL=chunk-
|
|
1265
|
+
//# sourceMappingURL=chunk-WRYZLEXP.js.map
|