chainlesschain 0.162.31 → 0.162.33
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/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-BqWP6FKu.js → AIOps-3TazCYWE.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXwMgOvX.js → ActionButton-DUPN0PST.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DAebZ4IY.js → Analytics-CemvhkzD.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CYsqYoME.js → AppLayout-BL_tAU3M.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-BbTtX1Nf.js → Audit-Dl9l-cxF.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DgqY2Eb-.js → Backup-BKDDX75m.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Cq2ZuSoO.js → BaseInput-CDYePvMI.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D2kqpUyO.js → Chat-CGtR0sg3.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DZjc9uKn.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-_9swHpyc.js → Checkbox-CwYIHOOo.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Cr9YbCPl.js → Codegen-CIF5tbtd.js} +1 -1
- package/src/assets/web-panel/assets/{Col--wdpCMxx.js → Col-z7d4kxeP.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DuFcVnLu.js → Community-DUlDrqF7.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-1yzYeT04.js → Compact-CJ1o8QQR.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Dq3aU9Df.js → Compliance-D3i9d_uO.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CrWcnIg8.js → Cowork-Wm7JTkfB.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Bh6fKZ0h.js → Cron-B0QnHhZx.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-8ofPaWVW.js → Crosschain-3yPrnNgd.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D3EiYm3w.js → DID-cfdkiDWF.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BFjEdFne.js → Dashboard-DFkgM4gT.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-pYVPcP6O.js → Dropdown-YYWE81DL.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-zBPodwJ1.js → EmailListRenderer-BXfHK1Bn.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CyQTW6PW.js → FamilyGuardDashboard-DInUxJ2G.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Ctaq3zYq.js → Federation-DNUYeFsv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CWYJCLq1.js → FormItemContext-Cr7eVEBB.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-B1g6t9R9.js → GenericCardRenderer-_gF4cmDa.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DH-v8iwd.js → Git-BqldmUbO.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-jZxXvOs5.js → Governance-BF59ZiQ8.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-D07LRghn.js → Inference-Cy7y1eb9.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DnGtRZhx.js → KnowledgeGraph-B3fVocTO.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-D2pM9C4W.js → Logs-BDirsUVk.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-UyIO7C7r.js → Marketplace-GhXpZgp2.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Bf1gvZPf.js → McpTools-0VvfIhKx.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-C1bWj4RN.js → Memory-CJLBgAUT.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C_Ot1H_a.js → MobileBridge-BMedY9Yg.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-mdohgRlL.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CnzFUz5J.js → Mtc-CgEuUg0g.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-CAAh99wz.js → MtcAudit-1pWNe_xi.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-D6IAg6HE.js → Multisig-DPIQ7oZL.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BFMarxb0.js → NLProgramming-W__P_P4Z.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BRp9ro3t.js → Notes-C_MCDhFk.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0Au3Cxb.js → NotificationSettings-CDFotapL.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Dtht0cEs.js +1 -0
- package/src/assets/web-panel/assets/{Organization-DYoxLBRX.js → Organization-D6lMumhD.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-rO8JJWGJ.js → Overflow-BMOvUMW6.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DJleeXIK.js → P2P-DsQTEw1t.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DM5qghFp.js → PdhVaultBrowser-CncRtN1Z.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D5v4Beya.js → Permissions-DDC-DkUl.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-c2ZTX0Pv.js → PersonalDataHub-DVKY_NnT.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-Crrkyhpz.js → Pipeline-C7oDVTl-.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DZVyrJKa.js → Privacy-DReGvTEJ.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DKg7J0gz.js → ProjectInit-C-j2dzxJ.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-3ndmTvVH.js → ProjectSettings-DcUsvFnc.js} +2 -2
- package/src/assets/web-panel/assets/Projects-jSjWnmr6.js +1 -0
- package/src/assets/web-panel/assets/{Providers-BeqBVMhB.js → Providers-DIpohWG5.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DKAAxzuA.js → QuickAsk-DdvLtpEU.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Byu7IGei.js → Recommend-DPAi2zo3.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-BKhWAmCu.js → Reputation-DJD7qXSI.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BFtn11O6.js → Row-XERdPDHk.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D5a0PT0k.js → RssFeed-Cl_VlCLg.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DAkuaZNe.js → Search-C-poG9P5.js} +1 -1
- package/src/assets/web-panel/assets/{Security-C79Ml2Ms.js → Security-DjjCrw8v.js} +2 -2
- package/src/assets/web-panel/assets/{Services-BBk_jH6-.js → Services-BuWeB4YJ.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Cy0VvL0M.js → Skeleton-VZXOKwC_.js} +1 -1
- package/src/assets/web-panel/assets/Skills-B76ONTfP.js +1 -0
- package/src/assets/web-panel/assets/{Sla-CbX1f8xN.js → Sla-DIj1KREq.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BIkoUjws.js → SpeechSettings-BrAp3Yk3.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DG6Swk7G.js → SyncSettings--mJcpccF.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-DM8cMr83.js +1 -0
- package/src/assets/web-panel/assets/{Templates-AaJPeCIz.js → Templates-kOBK6m1Z.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-jVFRofww.js → Tenant-BjSzYPzn.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DHBMzfK6.js → Terminal-DwpY-Ay7.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-9RFfOHSI.js → TimelineRenderer-aoI0DazM.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-ZTfwuABF.js → Tokens-YwE0LqSZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Xo7uZNQs.js → Trigger-CwSKzvlX.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-C0cTPYvn.js → Trust-B__Jqdzn.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DmMKio71.js → UkeySign-mty0jwmx.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DP7B-oGT.js → VideoEditing-Ddsx_OQ6.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-B1kZDARo.js → Wallet-D4Q8yXZm.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Bo5kBx27.js → WebAuthn-CLUaKUr5.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-DGI9SNHH.js → WorkflowEditor-Di5pOaeC.js} +1 -1
- package/src/assets/web-panel/assets/{chat-y97W1CIG.js → chat-CELatHkT.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DtTNo0sH.js → colors-CawDLjXV.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-D0q0exuS.js → compact-item-DeMp-K0j.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D7pLFs2I.js → createContext-zY9kXivd.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-zLjV7g6r.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CXjG5B2j.js → hasIn-VEBMW8E4.js} +1 -1
- package/src/assets/web-panel/assets/{index-TrBGgrwG.js → index-8kqE_cVD.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_4WcI1V.js → index-B8AZpx7d.js} +1 -1
- package/src/assets/web-panel/assets/{index-YWOEx3rP.js → index-BFc0vBN9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqVjUN8b.js → index-BVkrfyuk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnLrbXDA.js → index-BfGGKoo8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKrbutAQ.js → index-BjctklSd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFsPe2N7.js → index-BqJ2r12F.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSdhC7Qo.js → index-C0GhuYLk.js} +1 -1
- package/src/assets/web-panel/assets/index-CDtUWCtX.js +1 -0
- package/src/assets/web-panel/assets/{index-BO644Q4S.js → index-CHqvj9uz.js} +1 -1
- package/src/assets/web-panel/assets/{index-gFLQe31v.js → index-CHxHLv2b.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgyrM0UN.js → index-CWbbB1MI.js} +1 -1
- package/src/assets/web-panel/assets/{index-1dwtkcJv.js → index-CbJZzK9B.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3y_4OdG.js → index-CfZV3FXN.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dr45Nm9V.js → index-Cr7lnIeI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkGFqlYX.js → index-CtLZammH.js} +1 -1
- package/src/assets/web-panel/assets/{index-6np5ESBM.js → index-CtoauqWt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BU944DeT.js → index-CyeYs7SG.js} +1 -1
- package/src/assets/web-panel/assets/{index-POaFzYGS.js → index-DALuVdhu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjCawXk1.js → index-DClGYjBM.js} +1 -1
- package/src/assets/web-panel/assets/{index-8jxbZupG.js → index-DPHe9NYG.js} +1 -1
- package/src/assets/web-panel/assets/{index-_3wPBMKt.js → index-DSiL_W2n.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cbqu804A.js → index-DXNe_zIP.js} +1 -1
- package/src/assets/web-panel/assets/{index-EaIfumgW.js → index-DhsfyHcg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzCPx1cq.js → index-Dna2psGz.js} +1 -1
- package/src/assets/web-panel/assets/{index-kvV0f4tV.js → index-GRNVdvoA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdhEYW2a.js → index-JseP3-5X.js} +1 -1
- package/src/assets/web-panel/assets/{index-aarO4HT9.js → index-KcOEkUCM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgmvrPJH.js → index-S9JZDSaa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DY6KLlgG.js → index-SrQIPYq8.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ct6xtKkc.js → index-TfXODan7.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_hjkMtX.js → index-V3K9gvKR.js} +1 -1
- package/src/assets/web-panel/assets/{index-4mWZhCzz.js → index-VJnHvkv2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJUf19Wd.js → index-XFyv3Sg_.js} +3 -3
- package/src/assets/web-panel/assets/{index-B4dPdrvC.js → index-b3ZuAreb.js} +1 -1
- package/src/assets/web-panel/assets/index-d_RPqH7u.js +1 -0
- package/src/assets/web-panel/assets/{index-BPXhU-jp.js → index-fBNVDEf2.js} +1 -1
- package/src/assets/web-panel/assets/{index-bVJvqDAz.js → index-u_1aiNTA.js} +1 -1
- package/src/assets/web-panel/assets/{index-qoB3whR9.js → index-vaD1iHg5.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BnXISaAa.js → initDefaultProps-Sd7Eayz4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-ChY7C0zJ.js → motion-DlToY72q.js} +1 -1
- package/src/assets/web-panel/assets/{move-ByFZMFM5.js → move-DvS7EmAP.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BYeliY1H.js → omit-CzLq4QKW.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-B9dcAKnu.js → pickAttrs-BcM75Jx_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-D3F_txz7.js → placementArrow-B7xXXiwd.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-ClkwY7wS.js → responsiveObserve-CrYPRB-g.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BNgy2Eea.js → slide-CSYTtsRt.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Bv3heMCD.js → statusUtils-CeSuOVT_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DVdlHbQm.js → styleChecker-KiQethca.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-alrRY5BK.js → useFlexGapSupport-CSQnQdiv.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CcVh0-Vu.js → useFs-Br8Kr1pr.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CkkHPhyq.js → usePersonalDataHub-DGJtDcMm.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DWi0X9WN.js → vnode-C-jVtGka.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DCbqxxLH.js → zoom-CeWySTPF.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +47 -0
- package/src/commands/checkpoint.js +253 -53
- package/src/commands/compact.js +150 -0
- package/src/commands/goal.js +417 -0
- package/src/commands/hub.js +7 -0
- package/src/harness/prompt-compressor.js +71 -1
- package/src/index.js +4 -0
- package/src/lib/agent-core.js +1 -0
- package/src/lib/checkpoint-store.js +523 -0
- package/src/lib/goal-assess.js +228 -0
- package/src/lib/goal-context.js +87 -0
- package/src/lib/goal-store.js +341 -0
- package/src/repl/agent-repl.js +43 -7
- package/src/runtime/agent-core.js +267 -1
- package/src/runtime/headless-runner.js +147 -0
- package/src/runtime/headless-stream.js +34 -0
- package/src/runtime/mcp-config.js +139 -0
- package/src/runtime/policies/agent-policy.js +1 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-C-svYkrC.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-zr-PpsT_.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-ISp6btRY.js +0 -1
- package/src/assets/web-panel/assets/Projects-ll5wnj2L.js +0 -1
- package/src/assets/web-panel/assets/Skills-OQNky3uI.js +0 -1
- package/src/assets/web-panel/assets/Tasks-C9R8sgyi.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BDK34w0I.js +0 -1
- package/src/assets/web-panel/assets/index-B6SaRuCI.js +0 -1
- package/src/assets/web-panel/assets/index-B9ekWb3I.js +0 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc goal — cross-session persistent goals / OKRs.
|
|
3
|
+
*
|
|
4
|
+
* cc goal set <objective> [--title <t>] [--kr <text>...] create a goal
|
|
5
|
+
* cc goal list [--status active] [--json] list goals
|
|
6
|
+
* cc goal show <id> [--json] show one goal
|
|
7
|
+
* cc goal kr add <id> <text> [--target <n>] add a key result
|
|
8
|
+
* cc goal kr set <id> <krId> [--current <n>] [--done] update a key result
|
|
9
|
+
* cc goal progress <id> [--pct <n>] [--note <text>] record progress
|
|
10
|
+
* cc goal link <id> [sessionId] / unlink <id> [sessionId]
|
|
11
|
+
* cc goal pause|resume|close|abandon|rm <id> lifecycle
|
|
12
|
+
* cc goal active [--session <id>] [--json] the bound goal
|
|
13
|
+
*
|
|
14
|
+
* A goal is a long-lived objective the agent advances toward across sessions —
|
|
15
|
+
* distinct from `cc session` (short context), `cc memory` (facts),
|
|
16
|
+
* `cc planmode` (one run's plan) and `cc workflow` (execution state). When a
|
|
17
|
+
* goal is active it is injected into the agent loop each turn (goal-context.js).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
import { logger } from "../lib/logger.js";
|
|
22
|
+
|
|
23
|
+
const STATUS_COLOR = {
|
|
24
|
+
active: chalk.green,
|
|
25
|
+
paused: chalk.yellow,
|
|
26
|
+
done: chalk.cyan,
|
|
27
|
+
abandoned: chalk.gray,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function fmtStatus(s) {
|
|
31
|
+
return (STATUS_COLOR[s] || chalk.white)(s);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function printGoal(g, { verbose } = {}) {
|
|
35
|
+
logger.log(
|
|
36
|
+
`${chalk.bold(g.id)} ${fmtStatus(g.status)} ${chalk.gray(`${g.progress}%`)}`,
|
|
37
|
+
);
|
|
38
|
+
logger.log(` ${g.objective}`);
|
|
39
|
+
if (g.title && g.title !== g.objective) {
|
|
40
|
+
logger.log(chalk.gray(` title: ${g.title}`));
|
|
41
|
+
}
|
|
42
|
+
const open = (g.keyResults || []).filter((k) => !k.done).length;
|
|
43
|
+
const total = (g.keyResults || []).length;
|
|
44
|
+
if (total > 0) {
|
|
45
|
+
logger.log(chalk.gray(` key results: ${total - open}/${total} done`));
|
|
46
|
+
if (verbose) {
|
|
47
|
+
for (const kr of g.keyResults) {
|
|
48
|
+
const mark = kr.done ? chalk.green("✓") : chalk.gray("○");
|
|
49
|
+
const target = kr.target != null ? ` [${kr.current}/${kr.target}]` : "";
|
|
50
|
+
logger.log(` ${mark} ${chalk.dim(kr.id)} ${kr.text}${target}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (verbose) {
|
|
55
|
+
if (g.linkedSessions?.length) {
|
|
56
|
+
logger.log(chalk.gray(` sessions: ${g.linkedSessions.join(", ")}`));
|
|
57
|
+
}
|
|
58
|
+
if (g.notes?.length) {
|
|
59
|
+
logger.log(chalk.gray(` notes:`));
|
|
60
|
+
for (const n of g.notes.slice(-5)) {
|
|
61
|
+
logger.log(
|
|
62
|
+
chalk.gray(` [${n.at.slice(0, 16)}] (${n.by}) ${n.text}`),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
logger.log(
|
|
67
|
+
chalk.gray(` created: ${g.createdAt} updated: ${g.updatedAt}`),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function fail(action, err) {
|
|
73
|
+
logger.error(chalk.red(`goal ${action} failed: ${err.message}`));
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function registerGoalCommand(program) {
|
|
78
|
+
const goal = program
|
|
79
|
+
.command("goal")
|
|
80
|
+
.description("Cross-session persistent goals / OKRs");
|
|
81
|
+
|
|
82
|
+
// ── set (create) ──────────────────────────────────────────────────────
|
|
83
|
+
goal
|
|
84
|
+
.command("set <objective>")
|
|
85
|
+
.alias("add")
|
|
86
|
+
.description("Create a goal with an objective (and optional key results)")
|
|
87
|
+
.option("--title <title>", "Short title (defaults to the objective)")
|
|
88
|
+
.option(
|
|
89
|
+
"--kr <text>",
|
|
90
|
+
"Key result (repeatable)",
|
|
91
|
+
(v, acc) => (acc.push(v), acc),
|
|
92
|
+
[],
|
|
93
|
+
)
|
|
94
|
+
.option("--json", "Output as JSON")
|
|
95
|
+
.action(async (objective, options) => {
|
|
96
|
+
try {
|
|
97
|
+
const { createGoal } = await import("../lib/goal-store.js");
|
|
98
|
+
const g = createGoal({
|
|
99
|
+
objective,
|
|
100
|
+
title: options.title,
|
|
101
|
+
keyResults: options.kr || [],
|
|
102
|
+
});
|
|
103
|
+
if (options.json) {
|
|
104
|
+
console.log(JSON.stringify(g, null, 2));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
logger.log(chalk.green(`✓ goal ${chalk.bold(g.id)} created`));
|
|
108
|
+
printGoal(g, { verbose: true });
|
|
109
|
+
logger.log(
|
|
110
|
+
chalk.gray(
|
|
111
|
+
` bind to a run with: cc agent --goal ${g.id} (or it auto-binds when it is the only active goal)`,
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
fail("set", err);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// ── list ──────────────────────────────────────────────────────────────
|
|
120
|
+
goal
|
|
121
|
+
.command("list")
|
|
122
|
+
.alias("ls")
|
|
123
|
+
.description("List goals (newest first)")
|
|
124
|
+
.option("--status <status>", "Filter: active|paused|done|abandoned")
|
|
125
|
+
.option("--json", "Output as JSON")
|
|
126
|
+
.action(async (options) => {
|
|
127
|
+
try {
|
|
128
|
+
const { listGoals } = await import("../lib/goal-store.js");
|
|
129
|
+
const all = listGoals({ status: options.status });
|
|
130
|
+
if (options.json) {
|
|
131
|
+
console.log(JSON.stringify(all, null, 2));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (all.length === 0) {
|
|
135
|
+
logger.log(
|
|
136
|
+
chalk.gray("No goals. Create one: cc goal set <objective>"),
|
|
137
|
+
);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
for (const g of all) {
|
|
141
|
+
const open = (g.keyResults || []).filter((k) => !k.done).length;
|
|
142
|
+
const total = (g.keyResults || []).length;
|
|
143
|
+
const krInfo = total
|
|
144
|
+
? chalk.gray(` ${total - open}/${total} KR`)
|
|
145
|
+
: "";
|
|
146
|
+
// Soft drift hint: active goal with no progress recorded in 14+ days.
|
|
147
|
+
const stale = isStale(g);
|
|
148
|
+
logger.log(
|
|
149
|
+
`${chalk.cyan(g.id.padEnd(24))} ${fmtStatus(g.status).padEnd(18)} ${chalk.gray(`${String(g.progress).padStart(3)}%`)}${krInfo}` +
|
|
150
|
+
(stale ? chalk.yellow(" ⚠ stale") : "") +
|
|
151
|
+
`\n ${chalk.gray(truncate(g.objective, 80))}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
} catch (err) {
|
|
155
|
+
fail("list", err);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// ── show ──────────────────────────────────────────────────────────────
|
|
160
|
+
goal
|
|
161
|
+
.command("show <id>")
|
|
162
|
+
.description("Show a goal in full")
|
|
163
|
+
.option("--json", "Output as JSON")
|
|
164
|
+
.action(async (id, options) => {
|
|
165
|
+
try {
|
|
166
|
+
const { getGoal } = await import("../lib/goal-store.js");
|
|
167
|
+
const g = getGoal(id);
|
|
168
|
+
if (!g) {
|
|
169
|
+
logger.error(chalk.red(`no such goal: ${id}`));
|
|
170
|
+
process.exitCode = 1;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (options.json) {
|
|
174
|
+
console.log(JSON.stringify(g, null, 2));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
printGoal(g, { verbose: true });
|
|
178
|
+
} catch (err) {
|
|
179
|
+
fail("show", err);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// ── kr (key results) ──────────────────────────────────────────────────
|
|
184
|
+
const kr = goal.command("kr").description("Manage key results");
|
|
185
|
+
|
|
186
|
+
kr.command("add <id> <text>")
|
|
187
|
+
.description("Add a key result to a goal")
|
|
188
|
+
.option("--target <n>", "Numeric target for this key result")
|
|
189
|
+
.option("--json", "Output as JSON")
|
|
190
|
+
.action(async (id, text, options) => {
|
|
191
|
+
try {
|
|
192
|
+
const { addKeyResult } = await import("../lib/goal-store.js");
|
|
193
|
+
const g = addKeyResult(id, text, {
|
|
194
|
+
target: options.target != null ? Number(options.target) : null,
|
|
195
|
+
});
|
|
196
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
197
|
+
logger.log(chalk.green(`✓ key result added to ${id}`));
|
|
198
|
+
printGoal(g, { verbose: true });
|
|
199
|
+
} catch (err) {
|
|
200
|
+
fail("kr add", err);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
kr.command("set <id> <krId>")
|
|
205
|
+
.description("Update a key result's current value and/or mark it done")
|
|
206
|
+
.option("--current <n>", "Set the current value")
|
|
207
|
+
.option("--done", "Mark this key result done")
|
|
208
|
+
.option("--json", "Output as JSON")
|
|
209
|
+
.action(async (id, krId, options) => {
|
|
210
|
+
try {
|
|
211
|
+
const { setKeyResult } = await import("../lib/goal-store.js");
|
|
212
|
+
const g = setKeyResult(id, krId, {
|
|
213
|
+
current: options.current != null ? Number(options.current) : null,
|
|
214
|
+
done: options.done ? true : null,
|
|
215
|
+
});
|
|
216
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
217
|
+
logger.log(chalk.green(`✓ key result ${krId} updated`));
|
|
218
|
+
printGoal(g, { verbose: true });
|
|
219
|
+
} catch (err) {
|
|
220
|
+
fail("kr set", err);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// ── progress ──────────────────────────────────────────────────────────
|
|
225
|
+
goal
|
|
226
|
+
.command("progress <id>")
|
|
227
|
+
.description("Record progress: set a percentage and/or append a note")
|
|
228
|
+
.option("--pct <n>", "Progress percentage (0–100)")
|
|
229
|
+
.option("--note <text>", "Progress note")
|
|
230
|
+
.option("--json", "Output as JSON")
|
|
231
|
+
.action(async (id, options) => {
|
|
232
|
+
try {
|
|
233
|
+
const { recordProgress } = await import("../lib/goal-store.js");
|
|
234
|
+
if (options.pct == null && !options.note) {
|
|
235
|
+
logger.error(
|
|
236
|
+
chalk.red(
|
|
237
|
+
"nothing to record — pass --pct <n> and/or --note <text>",
|
|
238
|
+
),
|
|
239
|
+
);
|
|
240
|
+
process.exitCode = 1;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const g = recordProgress(id, {
|
|
244
|
+
pct: options.pct,
|
|
245
|
+
note: options.note,
|
|
246
|
+
by: "user",
|
|
247
|
+
});
|
|
248
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
249
|
+
logger.log(
|
|
250
|
+
chalk.green(`✓ progress recorded for ${id} (${g.progress}%)`),
|
|
251
|
+
);
|
|
252
|
+
} catch (err) {
|
|
253
|
+
fail("progress", err);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// ── link / unlink ─────────────────────────────────────────────────────
|
|
258
|
+
goal
|
|
259
|
+
.command("link <id> [sessionId]")
|
|
260
|
+
.description("Attach a session to a goal (defaults to the latest session)")
|
|
261
|
+
.option("--json", "Output as JSON")
|
|
262
|
+
.action(async (id, sessionId, options) => {
|
|
263
|
+
try {
|
|
264
|
+
const { linkSession } = await import("../lib/goal-store.js");
|
|
265
|
+
const sid = sessionId || (await latestSessionId());
|
|
266
|
+
if (!sid) {
|
|
267
|
+
logger.error(
|
|
268
|
+
chalk.red("no session id given and none could be inferred"),
|
|
269
|
+
);
|
|
270
|
+
process.exitCode = 1;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const g = linkSession(id, sid);
|
|
274
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
275
|
+
logger.log(chalk.green(`✓ linked session ${sid} to ${id}`));
|
|
276
|
+
} catch (err) {
|
|
277
|
+
fail("link", err);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
goal
|
|
282
|
+
.command("unlink <id> [sessionId]")
|
|
283
|
+
.description("Detach a session from a goal")
|
|
284
|
+
.option("--json", "Output as JSON")
|
|
285
|
+
.action(async (id, sessionId, options) => {
|
|
286
|
+
try {
|
|
287
|
+
const { unlinkSession } = await import("../lib/goal-store.js");
|
|
288
|
+
const sid = sessionId || (await latestSessionId());
|
|
289
|
+
const g = unlinkSession(id, sid);
|
|
290
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
291
|
+
logger.log(chalk.green(`✓ unlinked session ${sid} from ${id}`));
|
|
292
|
+
} catch (err) {
|
|
293
|
+
fail("unlink", err);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// ── lifecycle ─────────────────────────────────────────────────────────
|
|
298
|
+
const lifecycle = [
|
|
299
|
+
["pause", "paused", "paused"],
|
|
300
|
+
["resume", "active", "resumed"],
|
|
301
|
+
["close", "done", "closed (done)"],
|
|
302
|
+
["abandon", "abandoned", "abandoned"],
|
|
303
|
+
];
|
|
304
|
+
for (const [cmd, status, verb] of lifecycle) {
|
|
305
|
+
goal
|
|
306
|
+
.command(`${cmd} <id>`)
|
|
307
|
+
.description(`Mark a goal ${verb}`)
|
|
308
|
+
.option("--json", "Output as JSON")
|
|
309
|
+
.action(async (id, options) => {
|
|
310
|
+
try {
|
|
311
|
+
const { setStatus } = await import("../lib/goal-store.js");
|
|
312
|
+
const g = setStatus(id, status);
|
|
313
|
+
if (options.json) return void console.log(JSON.stringify(g, null, 2));
|
|
314
|
+
logger.log(chalk.green(`✓ goal ${id} ${verb}`));
|
|
315
|
+
} catch (err) {
|
|
316
|
+
fail(cmd, err);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
goal
|
|
322
|
+
.command("rm <id>")
|
|
323
|
+
.alias("delete")
|
|
324
|
+
.description("Delete a goal")
|
|
325
|
+
.option("--force", "Skip confirmation")
|
|
326
|
+
.action(async (id, options) => {
|
|
327
|
+
try {
|
|
328
|
+
const { deleteGoal } = await import("../lib/goal-store.js");
|
|
329
|
+
if (!options.force && process.stdin.isTTY) {
|
|
330
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
331
|
+
const ok = await confirm({
|
|
332
|
+
message: `Delete goal ${id}?`,
|
|
333
|
+
default: false,
|
|
334
|
+
}).catch(() => false);
|
|
335
|
+
if (!ok) {
|
|
336
|
+
logger.log(chalk.gray("Aborted."));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const existed = deleteGoal(id);
|
|
341
|
+
if (!existed) {
|
|
342
|
+
logger.error(chalk.red(`no such goal: ${id}`));
|
|
343
|
+
process.exitCode = 1;
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
logger.log(chalk.green(`✓ deleted ${id}`));
|
|
347
|
+
} catch (err) {
|
|
348
|
+
fail("rm", err);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// ── active (what's bound to a run) ────────────────────────────────────
|
|
353
|
+
goal
|
|
354
|
+
.command("active")
|
|
355
|
+
.description("Show the goal that would bind to a run (resolution order)")
|
|
356
|
+
.option("--session <id>", "Resolve as if this session were running")
|
|
357
|
+
.option("--json", "Output as JSON")
|
|
358
|
+
.action(async (options) => {
|
|
359
|
+
try {
|
|
360
|
+
const { resolveActiveGoal } = await import("../lib/goal-store.js");
|
|
361
|
+
const g = resolveActiveGoal({ sessionId: options.session });
|
|
362
|
+
if (options.json) {
|
|
363
|
+
console.log(JSON.stringify(g || null, null, 2));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (!g) {
|
|
367
|
+
logger.log(
|
|
368
|
+
chalk.gray(
|
|
369
|
+
"No goal would auto-bind (0 active goals, or several active and none linked — pass --goal <id> explicitly).",
|
|
370
|
+
),
|
|
371
|
+
);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
logger.log(chalk.bold("Bound goal:"));
|
|
375
|
+
printGoal(g, { verbose: true });
|
|
376
|
+
} catch (err) {
|
|
377
|
+
fail("active", err);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function truncate(s, n) {
|
|
383
|
+
s = String(s || "");
|
|
384
|
+
return s.length > n ? `${s.slice(0, n - 1)}…` : s;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Active goal with no progress recorded in 14+ days = soft drift hint. */
|
|
388
|
+
function isStale(g) {
|
|
389
|
+
if (g.status !== "active") return false;
|
|
390
|
+
const last = g.drift?.lastProgressAt || g.createdAt;
|
|
391
|
+
if (!last) return false;
|
|
392
|
+
const ageMs = Date.now() - new Date(last).getTime();
|
|
393
|
+
return ageMs > 14 * 24 * 60 * 60 * 1000;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Best-effort: the most recent session id, for `link` without an explicit id. */
|
|
397
|
+
async function latestSessionId() {
|
|
398
|
+
try {
|
|
399
|
+
const fs = await import("node:fs");
|
|
400
|
+
const path = await import("node:path");
|
|
401
|
+
const { sessionPath } = await import("../harness/jsonl-session-store.js");
|
|
402
|
+
// sessionPath("x") → <home>/sessions/x.jsonl — derive the dir from it.
|
|
403
|
+
const dir = path.dirname(sessionPath("x"));
|
|
404
|
+
if (!fs.existsSync(dir)) return null;
|
|
405
|
+
const files = fs
|
|
406
|
+
.readdirSync(dir)
|
|
407
|
+
.filter((f) => f.endsWith(".jsonl"))
|
|
408
|
+
.map((f) => ({
|
|
409
|
+
id: f.slice(0, -6),
|
|
410
|
+
mtime: fs.statSync(path.join(dir, f)).mtimeMs,
|
|
411
|
+
}))
|
|
412
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
413
|
+
return files[0]?.id || null;
|
|
414
|
+
} catch {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
}
|
package/src/commands/hub.js
CHANGED
|
@@ -351,6 +351,9 @@ async function cmdSyncAdapter(name, options) {
|
|
|
351
351
|
// sources (wechat-pc), --db-path as an explicit alias for the DB file.
|
|
352
352
|
if (options.key) opts.key = String(options.key);
|
|
353
353
|
if (options.dbPath) opts.dbPath = String(options.dbPath);
|
|
354
|
+
// QQ NT (qq-pc): the SQLCipher passphrase from qq-win-db-key (ASCII, e.g.
|
|
355
|
+
// "5{sww#,6aq=)8=A@"). Routes qq-pc through the decrypt+parse sidecar.
|
|
356
|
+
if (options.passphrase) opts.passphrase = String(options.passphrase);
|
|
354
357
|
// Cookie-mode sources (weread): pass the login cookie through to the adapter.
|
|
355
358
|
if (options.cookie) opts.cookie = String(options.cookie);
|
|
356
359
|
const report = await hub.registry.syncAdapter(name, opts);
|
|
@@ -2137,6 +2140,10 @@ export function registerHubCommand(program) {
|
|
|
2137
2140
|
"--key <hex>",
|
|
2138
2141
|
"SQLCipher key (64-hex) for encrypted local DBs (e.g. wechat-pc)",
|
|
2139
2142
|
)
|
|
2143
|
+
.option(
|
|
2144
|
+
"--passphrase <key>",
|
|
2145
|
+
'QQ NT SQLCipher passphrase from qq-win-db-key (ASCII, e.g. "5{sww#,6aq=)8=A@") — decrypts + parses qq-pc',
|
|
2146
|
+
)
|
|
2140
2147
|
.option(
|
|
2141
2148
|
"--cookie <cookie>",
|
|
2142
2149
|
"Login cookie for cookie-mode sources (e.g. weread)",
|
|
@@ -140,6 +140,70 @@ export function adaptiveThresholds(contextWindow) {
|
|
|
140
140
|
return result;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Repair tool-call/tool-result pairing after lossy compaction.
|
|
145
|
+
*
|
|
146
|
+
* Strict chat APIs reject a `tool` message whose `tool_call_id` has no
|
|
147
|
+
* preceding assistant `tool_calls`, and (for Anthropic) an assistant
|
|
148
|
+
* `tool_calls` with no following result. Count-based truncation / per-message
|
|
149
|
+
* snipping can orphan either side. This pass drops assistant tool_calls that
|
|
150
|
+
* lost their result, then drops tool results whose call was removed — leaving a
|
|
151
|
+
* sequence every provider will accept. Assistant messages whose calls are all
|
|
152
|
+
* orphaned are kept as plain text (if any) or dropped.
|
|
153
|
+
*
|
|
154
|
+
* @param {Array<object>} messages
|
|
155
|
+
* @returns {Array<object>} a new, balanced array
|
|
156
|
+
*/
|
|
157
|
+
export function sanitizeToolPairs(messages) {
|
|
158
|
+
if (!Array.isArray(messages)) return messages;
|
|
159
|
+
|
|
160
|
+
const resultIds = new Set(
|
|
161
|
+
messages
|
|
162
|
+
.filter((m) => m && m.role === "tool" && m.tool_call_id)
|
|
163
|
+
.map((m) => m.tool_call_id),
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Pass 1 — drop assistant tool_calls that have no matching tool result.
|
|
167
|
+
const stage1 = [];
|
|
168
|
+
for (const m of messages) {
|
|
169
|
+
if (
|
|
170
|
+
m &&
|
|
171
|
+
m.role === "assistant" &&
|
|
172
|
+
Array.isArray(m.tool_calls) &&
|
|
173
|
+
m.tool_calls.length
|
|
174
|
+
) {
|
|
175
|
+
const kept = m.tool_calls.filter((tc) => tc && resultIds.has(tc.id));
|
|
176
|
+
if (kept.length === m.tool_calls.length) {
|
|
177
|
+
stage1.push(m);
|
|
178
|
+
} else if (kept.length > 0) {
|
|
179
|
+
stage1.push({ ...m, tool_calls: kept });
|
|
180
|
+
} else {
|
|
181
|
+
// No surviving calls: keep the assistant text if any, else drop it.
|
|
182
|
+
const { tool_calls: _drop, ...rest } = m;
|
|
183
|
+
if (rest.content && String(rest.content).trim()) stage1.push(rest);
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
stage1.push(m);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Pass 2 — drop tool results whose call was removed in pass 1.
|
|
191
|
+
const survivingCallIds = new Set(
|
|
192
|
+
stage1
|
|
193
|
+
.filter((m) => m && m.role === "assistant" && Array.isArray(m.tool_calls))
|
|
194
|
+
.flatMap((m) => m.tool_calls.map((tc) => tc.id)),
|
|
195
|
+
);
|
|
196
|
+
return stage1.filter(
|
|
197
|
+
(m) =>
|
|
198
|
+
!(
|
|
199
|
+
m &&
|
|
200
|
+
m.role === "tool" &&
|
|
201
|
+
m.tool_call_id &&
|
|
202
|
+
!survivingCallIds.has(m.tool_call_id)
|
|
203
|
+
),
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
143
207
|
export class PromptCompressor {
|
|
144
208
|
constructor(options = {}) {
|
|
145
209
|
if (
|
|
@@ -217,6 +281,13 @@ export class PromptCompressor {
|
|
|
217
281
|
}
|
|
218
282
|
}
|
|
219
283
|
|
|
284
|
+
// Tool-pair repair (opt-in) — callers compacting tool-laden histories
|
|
285
|
+
// (e.g. the headless agent loop) pass this so truncation/snip never leaves
|
|
286
|
+
// an orphaned tool result or unanswered tool_call for a strict API.
|
|
287
|
+
if (options.preserveToolPairs) {
|
|
288
|
+
result = sanitizeToolPairs(result);
|
|
289
|
+
}
|
|
290
|
+
|
|
220
291
|
const compressedTokens = estimateMessagesTokens(result);
|
|
221
292
|
const stats = {
|
|
222
293
|
strategy: applied.join("+") || "none",
|
|
@@ -415,7 +486,6 @@ export class PromptCompressor {
|
|
|
415
486
|
}
|
|
416
487
|
}
|
|
417
488
|
|
|
418
|
-
|
|
419
489
|
// =====================================================================
|
|
420
490
|
// Prompt Compressor V2 governance overlay
|
|
421
491
|
// =====================================================================
|
package/src/index.js
CHANGED
|
@@ -58,6 +58,8 @@ import { registerRCacheCommand } from "./commands/rcache.js";
|
|
|
58
58
|
import { registerSessionCommand } from "./commands/session.js";
|
|
59
59
|
import { registerCostCommand } from "./commands/cost.js";
|
|
60
60
|
import { registerCheckpointCommand } from "./commands/checkpoint.js";
|
|
61
|
+
import { registerGoalCommand } from "./commands/goal.js";
|
|
62
|
+
import { registerCompactCommand } from "./commands/compact.js";
|
|
61
63
|
import { registerConsolCommand } from "./commands/consol.js";
|
|
62
64
|
import { registerImportCommand } from "./commands/import.js";
|
|
63
65
|
import { registerExportCommand } from "./commands/export.js";
|
|
@@ -452,6 +454,8 @@ export function createProgram(opts = {}) {
|
|
|
452
454
|
registerSessionCommand(program);
|
|
453
455
|
registerCostCommand(program);
|
|
454
456
|
registerCheckpointCommand(program);
|
|
457
|
+
registerGoalCommand(program);
|
|
458
|
+
registerCompactCommand(program);
|
|
455
459
|
registerConsolCommand(program);
|
|
456
460
|
|
|
457
461
|
// Phase 2: Knowledge & content management
|