chainlesschain 0.162.40 → 0.162.42
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 +1 -1
- package/src/assets/web-panel/assets/{AIOps-CPmKv82o.js → AIOps-Dsw5p7A7.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BNDYY7Qd.js → ActionButton-sk89dGuT.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BgCMCOsk.js → Analytics-kd8hzeK3.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Dv4oJcqS.js → AppLayout-CxlLp7J8.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-5iV3yrGa.js → Audit-CQnGmRxA.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CHDhnbzF.js → Backup-BioBFWVV.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B6reFkra.js → BaseInput-DiYG1n7T.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DwS5YyE2.js → Chat-BBuQf6VM.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CqXa87Hw.js → ChatBubbleRenderer-BwgFmlRu.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-yiW0M4RE.js → Checkbox-B-9WwFTA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DoiVuD_g.js → Codegen-DCkpThQa.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BVASLexk.js → Col-BowFdito.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D6KQ7JoU.js → Community-BWGa92rE.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Bl9Uhb6v.js → Compact-CqJYYK0v.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-MM31-dba.js → Compliance-DiFqpJrM.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-PjU_1ieD.js → Cowork-qZNWcSQ9.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DorNtPZL.js → Cron-BK70XYci.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Bm5ts2Kw.js → Crosschain-DoM9N2kO.js} +1 -1
- package/src/assets/web-panel/assets/{DID-7Y3jlFdY.js → DID-B1F1RhQr.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-1oE532bG.js → Dashboard-CmDxx07G.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-hJlOPs0s.js → Dropdown-5GRByJY9.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BEqJxKaO.js → EmailListRenderer-CyNgNjLG.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BvCGwB6X.js → FamilyGuardDashboard-Jwg-Wuye.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CsXI72e5.js → Federation-BQvoY2_5.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Dh9SMul-.js → FormItemContext-DKy8Zatd.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-9edWzrtG.js → GenericCardRenderer-n7VGwZNh.js} +1 -1
- package/src/assets/web-panel/assets/{Git-ZYhNL8Xk.js → Git-CFCUe_so.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BwAdp8QA.js → Governance-DuZbRElA.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-5C-M1XsH.js → Inference-DSEsBonV.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-zFAi-zCi.js → KnowledgeGraph-DQoaeSnN.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BZsEdbgE.js → Logs-u7UMHPnz.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-BP6gErRK.js → Marketplace--gDqWnX8.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CXVzoLrd.js → McpTools-btiDEQ_G.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BIpChb4-.js → Memory-CYrqC903.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-B4O7wDT8.js → MobileBridge-CktV5fRJ.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-CTVZQD7g.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BTmEyTM5.js → Mtc-CRq5Ir7q.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-CsbG9LlV.js → MtcAudit-HvY-N0XZ.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CL8yoGon.js → Multisig-CWmUSW7g.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C2cIlIp_.js → NLProgramming-BUwhn6xG.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-7aBk_n_M.js → Notes-BI8NqNSW.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BuhQk4rJ.js → NotificationSettings-DVa8gbo1.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-mqMFZu0x.js → OrderTableRenderer-XNEr64wi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CAdq-170.js → Organization-a0imltNQ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow--Xn0E787.js → Overflow-DJ2P1mNg.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DYt3YAXI.js → P2P-pRJPEJ7a.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Bgb_v8WN.js → PdhVaultBrowser-eJa8vkF5.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DoFlmoaW.js → Permissions-fxa21qzR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C-FJB3a0.js → PersonalDataHub-C3JggyPn.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-3bL2RzzL.js → Pipeline-iR9fwke0.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-c4igYUCF.js → Privacy-oBf4gwv0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C0QS1UPR.js → ProjectInit-DZU2PVgs.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CkYC0xkE.js → ProjectSettings-amcXcSet.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Di17SYft.js → Projects-QoksY3-i.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-41NySsLt.js → Providers-uquz_5KZ.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DHq9pD7z.js → QuickAsk-Wxx-iIH9.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CLjgFPLv.js → Recommend-CD8OJGJF.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-EIrgErm3.js → Reputation-BuJMHfco.js} +1 -1
- package/src/assets/web-panel/assets/{Row-GAvKzKH7.js → Row-DvfqASM7.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CYCNsVmD.js → RssFeed-TGSmYgmV.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DWOE32k8.js → Search-ndSDi33l.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Dgh8Jevn.js → Security-CL1FLyzy.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BxdgP67N.js → Services--AeNKFrY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D-xT4ZkA.js → Skeleton-CMllAeqY.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BKN4lfSa.js → Skills-DD29bVTm.js} +1 -1
- package/src/assets/web-panel/assets/{Sla--N1TudpS.js → Sla-DU_Mdrad.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-B0vfJpEh.js → SpeechSettings-Cu0ncgI_.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BuBAbPAh.js → SyncSettings-Bfk00Eb9.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-C-2V1COO.js +1 -0
- package/src/assets/web-panel/assets/{Templates-DI2giLgc.js → Templates-CWO4Aw1l.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BiTWvm0g.js → Tenant-BnDkNC6u.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-VR0JLDdw.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-BmgzKdAp.js → TimelineRenderer-DMjbfev0.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Nvupdm6p.js → Tokens-j1ZGEgBP.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DRfR77WJ.js → Trigger-BKVNLlOB.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-De0Jal_6.js → Trust-Bbfv8AJr.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Dzo4-VAM.js → UkeySign-C0_Gllsu.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-hg2ytiJB.js → VideoEditing-CE__3Owf.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet--bU5-gRh.js → Wallet-Cjzavume.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DZptt-PV.js → WebAuthn-KbjxueWc.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Dy9223bY.js → WorkflowEditor-Bz7UuLhK.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DaxGeI9w.js → chat-BrSAQ_Gd.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Cu2VEci3.js → colors-Bn8oqI93.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CGolhyJq.js → compact-item-jxrLqj8Q.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DY7EFhkD.js → createContext-B0uxIvgB.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-rqonNzey.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Bpc-NoFN.js → hasIn-BFsfry47.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQ2z6Ky5.js → index-9iuxVwRC.js} +1 -1
- package/src/assets/web-panel/assets/{index-eF9RV_4c.js → index-B9ZDJUc0.js} +1 -1
- package/src/assets/web-panel/assets/index-BI1fCgPX.js +1 -0
- package/src/assets/web-panel/assets/{index-VBRPxZeE.js → index-BPpGWBAU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlHq81Ow.js → index-BQZsB8nt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjfxHEmX.js → index-BQvlv_iE.js} +1 -1
- package/src/assets/web-panel/assets/{index-8h9y5S6X.js → index-BRkK0yoO.js} +1 -1
- package/src/assets/web-panel/assets/{index-lfP8sdzB.js → index-BY4oOQaA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bz83ngs0.js → index-Bd-zsWvY.js} +1 -1
- package/src/assets/web-panel/assets/{index-BP9P6chP.js → index-BiXyJmcf.js} +1 -1
- package/src/assets/web-panel/assets/{index-D63ObMdQ.js → index-Bk_Tv7Ey.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0GN5tdM.js → index-BzZfG8Ft.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNX81oSR.js → index-C6AmzUjG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTvwiqJE.js → index-C7q_gApa.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2RpsAiO.js → index-CAIdm73g.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bn5gM9Oy.js → index-CCVF9irI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DexYD87j.js → index-CR3QNisI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfKmAEtE.js → index-CZ8gyTGc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRAgl2J_.js → index-CireH7ze.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpRSzAFl.js → index-CovEs7is.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-Hkl_2G.js → index-Crqzhccj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DldaToUA.js → index-D08W2YxD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAov-rJR.js → index-D1WrY_4z.js} +1 -1
- package/src/assets/web-panel/assets/index-D8iCZ8gl.js +1 -0
- package/src/assets/web-panel/assets/{index-oJQgRCrR.js → index-DMPQqeLb.js} +3 -3
- package/src/assets/web-panel/assets/{index-Ciw5-X1B.js → index-DOJYoYG7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJFYF8F9.js → index-DSDgBgrL.js} +1 -1
- package/src/assets/web-panel/assets/{index-1D4sfByw.js → index-DcHQBw3b.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLNqZF55.js → index-DdjhDnIk.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGqeHu_F.js → index-DeHd8uSh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZ4Vm8dQ.js → index-DjxJSCB8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFAnEzRW.js → index-DmD-qtjF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0_zeYnx.js → index-DteDdzDQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBSk_VrT.js → index-E6sYKDbw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaKXhpEu.js → index-LLFwwG0R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxXkr-NS.js → index-_fgTMPd1.js} +1 -1
- package/src/assets/web-panel/assets/{index-RumxOD0S.js → index-pMVcl-a3.js} +1 -1
- package/src/assets/web-panel/assets/{index-rkm7dHwG.js → index-vma7bVdQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DElatOQ0.js → index-xRD9Fctn.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CkJZfCo8.js → initDefaultProps-AKS5cCeZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BerbusV1.js → motion-SDjWiFhF.js} +1 -1
- package/src/assets/web-panel/assets/{move-DyRzKPD4.js → move-LEZnOtYR.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CCdrTUAs.js → omit-DhLBVNzX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-mVDeZx2m.js → pickAttrs-DdVSELea.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Bb_-Fs_o.js → placementArrow-BaEGCCq9.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C6TMj1R_.js → responsiveObserve-DV6XM19W.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CdCNsy1J.js → slide-BOUnaBay.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ccxd1rFd.js → statusUtils-BAaMQ0VA.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-3IL-yw1V.js → styleChecker-CsoP0nmm.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CH8DjUHl.js → useFlexGapSupport-t20RbINy.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Cn9nE2sp.js → useFs-DH_Emn7A.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BPyT0HO7.js → usePersonalDataHub-CeYW427U.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Mfm7vy07.js → vnode-CX5gGmGb.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CTpAiAE9.js → zoom-CofyY9oD.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +38 -4
- package/src/commands/init.js +31 -0
- package/src/commands/mcp.js +57 -0
- package/src/commands/memory.js +62 -0
- package/src/commands/session.js +70 -0
- package/src/lib/agent-core.js +1 -0
- package/src/lib/init-ai-refine.js +66 -0
- package/src/lib/json-schema-output.js +181 -0
- package/src/lib/mcp-serve.js +259 -0
- package/src/lib/project-instructions.js +89 -0
- package/src/lib/repl-completer.js +9 -3
- package/src/lib/repl-rewind.js +107 -0
- package/src/repl/agent-repl.js +145 -1
- package/src/runtime/headless-stream.js +60 -0
- package/src/assets/web-panel/assets/MobileProjects-7VPMoHus.js +0 -1
- package/src/assets/web-panel/assets/Tasks-4XugjJ87.js +0 -1
- package/src/assets/web-panel/assets/Terminal-vV6AWGDi.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DV2BNd59.js +0 -1
- package/src/assets/web-panel/assets/index-BZqtTmyG.js +0 -1
- package/src/assets/web-panel/assets/index-DUpwdJt9.js +0 -1
package/src/commands/mcp.js
CHANGED
|
@@ -214,6 +214,63 @@ export function registerMcpCommand(program) {
|
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
216
|
|
|
217
|
+
// mcp serve — expose THIS machine's files as an MCP server
|
|
218
|
+
mcp
|
|
219
|
+
.command("serve")
|
|
220
|
+
.description(
|
|
221
|
+
"Expose local file tools (read/list/search/write, root-confined) as a Streamable-HTTP MCP server for other clients",
|
|
222
|
+
)
|
|
223
|
+
.option("--port <n>", "Port to listen on (default: random free port)", "0")
|
|
224
|
+
.option("--root <dir>", "Serve root directory (default: cwd)")
|
|
225
|
+
.option("--read-only", "Disable the write_file tool")
|
|
226
|
+
.option("--token <token>", "Fixed Bearer token (default: random)")
|
|
227
|
+
.option("--no-auth", "Disable Bearer auth (server binds 127.0.0.1 only)")
|
|
228
|
+
.action(async (options) => {
|
|
229
|
+
try {
|
|
230
|
+
const { startMcpServe } = await import("../lib/mcp-serve.js");
|
|
231
|
+
const handle = await startMcpServe({
|
|
232
|
+
root: options.root,
|
|
233
|
+
port: Number(options.port) || 0,
|
|
234
|
+
readOnly: Boolean(options.readOnly),
|
|
235
|
+
token: options.auth === false ? false : options.token || null,
|
|
236
|
+
});
|
|
237
|
+
logger.log(chalk.bold("MCP server ready (Streamable-HTTP)"));
|
|
238
|
+
logger.log(` URL: ${chalk.cyan(handle.url)}`);
|
|
239
|
+
logger.log(` Root: ${handle.root}${handle.readOnly ? " (read-only)" : ""}`);
|
|
240
|
+
if (handle.token) {
|
|
241
|
+
logger.log(` Auth: Bearer ${handle.token}`);
|
|
242
|
+
} else {
|
|
243
|
+
logger.log(chalk.yellow(" Auth: disabled (--no-auth)"));
|
|
244
|
+
}
|
|
245
|
+
logger.log(chalk.gray("\nConnect from another cc via --mcp-config:"));
|
|
246
|
+
logger.log(
|
|
247
|
+
chalk.gray(
|
|
248
|
+
JSON.stringify(
|
|
249
|
+
{
|
|
250
|
+
mcpServers: {
|
|
251
|
+
ccfiles: {
|
|
252
|
+
transport: "http",
|
|
253
|
+
url: handle.url,
|
|
254
|
+
...(handle.token
|
|
255
|
+
? { headers: { Authorization: `Bearer ${handle.token}` } }
|
|
256
|
+
: {}),
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
null,
|
|
261
|
+
2,
|
|
262
|
+
),
|
|
263
|
+
),
|
|
264
|
+
);
|
|
265
|
+
logger.log(chalk.gray("\nCtrl+C to stop."));
|
|
266
|
+
// keep the process alive until killed
|
|
267
|
+
await new Promise(() => {});
|
|
268
|
+
} catch (err) {
|
|
269
|
+
logger.error(chalk.red(`mcp serve failed: ${err.message}`));
|
|
270
|
+
process.exitCode = 1;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
217
274
|
// mcp servers — list configured servers
|
|
218
275
|
mcp
|
|
219
276
|
.command("servers")
|
package/src/commands/memory.js
CHANGED
|
@@ -53,6 +53,68 @@ export function registerMemoryCommand(program) {
|
|
|
53
53
|
.command("memory")
|
|
54
54
|
.description("Persistent memory and daily notes");
|
|
55
55
|
|
|
56
|
+
// memory files — observability for the cc.md project-memory loader
|
|
57
|
+
memory
|
|
58
|
+
.command("files")
|
|
59
|
+
.description(
|
|
60
|
+
"List the project-memory files cc agent auto-loads here (cc.md hierarchy + imports + path-scoped rules)",
|
|
61
|
+
)
|
|
62
|
+
.option("--cwd <dir>", "Inspect from this directory instead of cwd")
|
|
63
|
+
.option("--json", "Output as JSON")
|
|
64
|
+
.action(async (options) => {
|
|
65
|
+
try {
|
|
66
|
+
const { loadProjectInstructions } = await import(
|
|
67
|
+
"../lib/project-instructions.js"
|
|
68
|
+
);
|
|
69
|
+
const cwd = options.cwd || process.cwd();
|
|
70
|
+
const loaded = loadProjectInstructions({ cwd });
|
|
71
|
+
if (options.json) {
|
|
72
|
+
console.log(
|
|
73
|
+
JSON.stringify(
|
|
74
|
+
{
|
|
75
|
+
cwd,
|
|
76
|
+
files: loaded.files.map((f) => ({
|
|
77
|
+
path: f.path,
|
|
78
|
+
scope: f.scope,
|
|
79
|
+
bytes: f.bytes,
|
|
80
|
+
truncated: f.truncated,
|
|
81
|
+
})),
|
|
82
|
+
warnings: loaded.warnings,
|
|
83
|
+
},
|
|
84
|
+
null,
|
|
85
|
+
2,
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!loaded.files.length) {
|
|
91
|
+
logger.log(
|
|
92
|
+
"No project-memory files found — run `cc init` to generate a cc.md.",
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
logger.log(chalk.bold("Project memory loaded by cc agent:"));
|
|
97
|
+
for (const f of loaded.files) {
|
|
98
|
+
logger.log(
|
|
99
|
+
` [${f.scope.padEnd(7)}] ${f.path} ${chalk.gray(
|
|
100
|
+
`${f.bytes} bytes${f.truncated ? " (truncated)" : ""}`,
|
|
101
|
+
)}`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
for (const w of loaded.warnings) {
|
|
105
|
+
logger.log(chalk.yellow(` ⚠ ${w}`));
|
|
106
|
+
}
|
|
107
|
+
logger.log(
|
|
108
|
+
chalk.gray(
|
|
109
|
+
"Disable with CC_PROJECT_MEMORY=0 · file precedence: cc.md > CLAUDE.md > AGENTS.md",
|
|
110
|
+
),
|
|
111
|
+
);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
logger.error(`memory files failed: ${err.message}`);
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
56
118
|
// memory show
|
|
57
119
|
memory
|
|
58
120
|
.command("show", { isDefault: true })
|
package/src/commands/session.js
CHANGED
|
@@ -343,6 +343,76 @@ export function registerSessionCommand(program) {
|
|
|
343
343
|
}
|
|
344
344
|
});
|
|
345
345
|
|
|
346
|
+
// session search — full-text search across agent transcripts (JSONL store)
|
|
347
|
+
session
|
|
348
|
+
.command("search")
|
|
349
|
+
.description(
|
|
350
|
+
"Full-text search across agent session transcripts (JSONL --resume store)",
|
|
351
|
+
)
|
|
352
|
+
.argument("<query>", "Text to find (case-insensitive)")
|
|
353
|
+
.option("-n, --limit <n>", "Max matches", "20")
|
|
354
|
+
.option("--sessions <n>", "Max recent sessions to scan", "200")
|
|
355
|
+
.option("--json", "Output as JSON")
|
|
356
|
+
.action(async (query, options) => {
|
|
357
|
+
try {
|
|
358
|
+
const store = await import("../harness/jsonl-session-store.js");
|
|
359
|
+
const q = String(query).toLowerCase();
|
|
360
|
+
const limit = Number(options.limit) || 20;
|
|
361
|
+
const sessions = store.listJsonlSessions({
|
|
362
|
+
limit: Number(options.sessions) || 200,
|
|
363
|
+
});
|
|
364
|
+
const matches = [];
|
|
365
|
+
for (const s of sessions) {
|
|
366
|
+
if (matches.length >= limit) break;
|
|
367
|
+
for (const ev of store.readEvents(s.id)) {
|
|
368
|
+
if (matches.length >= limit) break;
|
|
369
|
+
if (ev.type !== "user_message" && ev.type !== "assistant_message")
|
|
370
|
+
continue;
|
|
371
|
+
const text =
|
|
372
|
+
typeof ev.data?.content === "string"
|
|
373
|
+
? ev.data.content
|
|
374
|
+
: JSON.stringify(ev.data?.content || "");
|
|
375
|
+
const idx = text.toLowerCase().indexOf(q);
|
|
376
|
+
if (idx === -1) continue;
|
|
377
|
+
const from = Math.max(0, idx - 30);
|
|
378
|
+
matches.push({
|
|
379
|
+
session: s.id,
|
|
380
|
+
title: s.title,
|
|
381
|
+
role: ev.type === "user_message" ? "user" : "assistant",
|
|
382
|
+
when: ev.timestamp ? new Date(ev.timestamp).toISOString() : "",
|
|
383
|
+
preview: text
|
|
384
|
+
.slice(from, idx + q.length + 50)
|
|
385
|
+
.replace(/\s+/g, " ")
|
|
386
|
+
.trim(),
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (options.json) {
|
|
391
|
+
console.log(JSON.stringify({ query, matches }, null, 2));
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (!matches.length) {
|
|
395
|
+
logger.log(`No matches for "${query}".`);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
logger.log(chalk.bold(`Matches for "${query}":`));
|
|
399
|
+
for (const m of matches) {
|
|
400
|
+
logger.log(
|
|
401
|
+
` ${chalk.cyan(m.session)} ${chalk.gray(`[${m.role}${m.when ? ` ${m.when.slice(0, 16)}` : ""}]`)}`,
|
|
402
|
+
);
|
|
403
|
+
logger.log(` …${m.preview}…`);
|
|
404
|
+
}
|
|
405
|
+
logger.log(
|
|
406
|
+
chalk.gray(
|
|
407
|
+
`\n${matches.length} match(es) · resume one with: cc agent --resume <session>`,
|
|
408
|
+
),
|
|
409
|
+
);
|
|
410
|
+
} catch (err) {
|
|
411
|
+
logger.error(`session search failed: ${err.message}`);
|
|
412
|
+
process.exitCode = 1;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
346
416
|
// session delete
|
|
347
417
|
session
|
|
348
418
|
.command("delete")
|
package/src/lib/agent-core.js
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc init --ai` — agent-enhanced inventory (claude /init parity, module 99
|
|
3
|
+
* §5.2). Runs AFTER the offline census wrote the starter cc.md: a bounded
|
|
4
|
+
* headless agent reads the repo (README, entry files) and rewrites cc.md so
|
|
5
|
+
* the Conventions section holds real, observed conventions instead of the
|
|
6
|
+
* "(add project rules here)" placeholder.
|
|
7
|
+
*
|
|
8
|
+
* Self-reference guard: the child run executes with CC_PROJECT_MEMORY=0 so
|
|
9
|
+
* the half-baked cc.md being refined is NOT injected into the very agent
|
|
10
|
+
* refining it. Restored in finally.
|
|
11
|
+
*
|
|
12
|
+
* Offline inventory stays the `cc init` default — this is strictly opt-in
|
|
13
|
+
* (needs a reachable LLM).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const AI_REFINE_MAX_TURNS = 12;
|
|
17
|
+
export const AI_REFINE_TOOLS = [
|
|
18
|
+
"read_file",
|
|
19
|
+
"list_dir",
|
|
20
|
+
"search_files",
|
|
21
|
+
"write_file",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export function buildRefinePrompt() {
|
|
25
|
+
return [
|
|
26
|
+
"You are refining this project's memory file `cc.md` (it was just generated from an offline folder census).",
|
|
27
|
+
"Steps:",
|
|
28
|
+
"1. read_file cc.md to see the current draft.",
|
|
29
|
+
"2. Read the README and one or two key entry/config files to learn the project's real conventions (code style, commit format, how to run tests, architecture notes worth remembering).",
|
|
30
|
+
"3. write_file cc.md with the refined version: KEEP the existing sections and data, but replace the placeholder under `## Conventions` with concrete, observed conventions (5-10 short bullets max). Do not invent facts you did not see.",
|
|
31
|
+
"Keep the file concise — it is loaded into every agent run.",
|
|
32
|
+
].join("\n");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Run the refine pass.
|
|
37
|
+
* @param {object} opts { cwd, provider?, model?, baseUrl?, apiKey?,
|
|
38
|
+
* maxTurns?, runHeadless? (test seam) }
|
|
39
|
+
* @returns {Promise<{exitCode:number, result:string, isError:boolean}>}
|
|
40
|
+
*/
|
|
41
|
+
export async function aiRefineMemoryFile(opts = {}) {
|
|
42
|
+
const run =
|
|
43
|
+
opts.runHeadless ||
|
|
44
|
+
(await import("../runtime/headless-runner.js")).runAgentHeadless;
|
|
45
|
+
|
|
46
|
+
const prev = process.env.CC_PROJECT_MEMORY;
|
|
47
|
+
process.env.CC_PROJECT_MEMORY = "0"; // self-reference guard
|
|
48
|
+
try {
|
|
49
|
+
return await run({
|
|
50
|
+
prompt: buildRefinePrompt(),
|
|
51
|
+
cwd: opts.cwd || process.cwd(),
|
|
52
|
+
provider: opts.provider || undefined,
|
|
53
|
+
model: opts.model || undefined,
|
|
54
|
+
baseUrl: opts.baseUrl || undefined,
|
|
55
|
+
apiKey: opts.apiKey || undefined,
|
|
56
|
+
permissionMode: "acceptEdits", // write_file must work headless
|
|
57
|
+
allowedTools: AI_REFINE_TOOLS,
|
|
58
|
+
maxTurns: opts.maxTurns || AI_REFINE_MAX_TURNS,
|
|
59
|
+
expandFileRefs: false,
|
|
60
|
+
outputFormat: "text",
|
|
61
|
+
});
|
|
62
|
+
} finally {
|
|
63
|
+
if (prev === undefined) delete process.env.CC_PROJECT_MEMORY;
|
|
64
|
+
else process.env.CC_PROJECT_MEMORY = prev;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc agent -p --json-schema <file>` — structured output for headless runs.
|
|
3
|
+
*
|
|
4
|
+
* The final answer must be JSON that validates against a (subset) JSON
|
|
5
|
+
* Schema; invalid replies are retried with a corrective prompt (up to
|
|
6
|
+
* MAX_ATTEMPTS total). Implemented entirely AROUND runAgentHeadless using its
|
|
7
|
+
* `deps.writeOut` capture seam — the runner itself is untouched: each attempt
|
|
8
|
+
* runs with output captured, the validated JSON is the only thing printed.
|
|
9
|
+
*
|
|
10
|
+
* Validator subset (enough for tool/script contracts, not full draft-2020):
|
|
11
|
+
* type (object/array/string/number/integer/boolean/null), properties,
|
|
12
|
+
* required, items, enum, const, additionalProperties:false. Zero deps.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import fsDefault from "fs";
|
|
16
|
+
|
|
17
|
+
export const MAX_ATTEMPTS = 3;
|
|
18
|
+
export const _deps = { fs: fsDefault };
|
|
19
|
+
|
|
20
|
+
/** Validate `value` against the schema subset. Returns error strings ([] = valid). */
|
|
21
|
+
export function validateAgainstSchema(value, schema, path = "$") {
|
|
22
|
+
const errors = [];
|
|
23
|
+
if (!schema || typeof schema !== "object") return errors;
|
|
24
|
+
|
|
25
|
+
const typeOf = (v) =>
|
|
26
|
+
v === null
|
|
27
|
+
? "null"
|
|
28
|
+
: Array.isArray(v)
|
|
29
|
+
? "array"
|
|
30
|
+
: typeof v === "number" && Number.isInteger(v)
|
|
31
|
+
? "integer"
|
|
32
|
+
: typeof v;
|
|
33
|
+
|
|
34
|
+
if (schema.type) {
|
|
35
|
+
const want = Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
36
|
+
const got = typeOf(value);
|
|
37
|
+
const ok = want.some((t) => t === got || (t === "number" && got === "integer"));
|
|
38
|
+
if (!ok) {
|
|
39
|
+
errors.push(`${path}: expected type ${want.join("|")}, got ${got}`);
|
|
40
|
+
return errors; // type mismatch — deeper checks are noise
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (schema.enum && !schema.enum.some((e) => JSON.stringify(e) === JSON.stringify(value))) {
|
|
44
|
+
errors.push(`${path}: value not in enum [${schema.enum.map((e) => JSON.stringify(e)).join(", ")}]`);
|
|
45
|
+
}
|
|
46
|
+
if (schema.const !== undefined && JSON.stringify(schema.const) !== JSON.stringify(value)) {
|
|
47
|
+
errors.push(`${path}: must equal const ${JSON.stringify(schema.const)}`);
|
|
48
|
+
}
|
|
49
|
+
if (typeOf(value) === "object" && !Array.isArray(value)) {
|
|
50
|
+
for (const req of schema.required || []) {
|
|
51
|
+
if (!(req in value)) errors.push(`${path}: missing required property "${req}"`);
|
|
52
|
+
}
|
|
53
|
+
const props = schema.properties || {};
|
|
54
|
+
for (const [k, v] of Object.entries(value)) {
|
|
55
|
+
if (props[k]) {
|
|
56
|
+
errors.push(...validateAgainstSchema(v, props[k], `${path}.${k}`));
|
|
57
|
+
} else if (schema.additionalProperties === false) {
|
|
58
|
+
errors.push(`${path}: unexpected property "${k}"`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(value) && schema.items) {
|
|
63
|
+
value.forEach((item, i) => {
|
|
64
|
+
errors.push(...validateAgainstSchema(item, schema.items, `${path}[${i}]`));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return errors;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Pull a JSON payload out of an LLM reply (bare, fenced, or embedded). */
|
|
71
|
+
export function extractJsonPayload(text) {
|
|
72
|
+
const raw = String(text || "").trim();
|
|
73
|
+
const tries = [];
|
|
74
|
+
tries.push(raw);
|
|
75
|
+
const fence = /```(?:json)?\s*([\s\S]*?)```/i.exec(raw);
|
|
76
|
+
if (fence) tries.push(fence[1].trim());
|
|
77
|
+
const firstObj = raw.indexOf("{");
|
|
78
|
+
const lastObj = raw.lastIndexOf("}");
|
|
79
|
+
if (firstObj !== -1 && lastObj > firstObj) tries.push(raw.slice(firstObj, lastObj + 1));
|
|
80
|
+
const firstArr = raw.indexOf("[");
|
|
81
|
+
const lastArr = raw.lastIndexOf("]");
|
|
82
|
+
if (firstArr !== -1 && lastArr > firstArr) tries.push(raw.slice(firstArr, lastArr + 1));
|
|
83
|
+
for (const candidate of tries) {
|
|
84
|
+
if (!candidate) continue;
|
|
85
|
+
try {
|
|
86
|
+
return { ok: true, value: JSON.parse(candidate) };
|
|
87
|
+
} catch {
|
|
88
|
+
/* next candidate */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { ok: false, error: "reply contains no parseable JSON" };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function buildSchemaInstruction(schema) {
|
|
95
|
+
return [
|
|
96
|
+
"OUTPUT CONTRACT: your FINAL reply must be ONLY a JSON value (no prose, no markdown fences) that validates against this JSON Schema:",
|
|
97
|
+
JSON.stringify(schema),
|
|
98
|
+
].join("\n");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function buildRetryPrompt(originalPrompt, raw, errors) {
|
|
102
|
+
return [
|
|
103
|
+
originalPrompt,
|
|
104
|
+
"",
|
|
105
|
+
"Your previous reply failed JSON Schema validation:",
|
|
106
|
+
...errors.slice(0, 10).map((e) => `- ${e}`),
|
|
107
|
+
"",
|
|
108
|
+
`Previous reply (for reference): ${String(raw).slice(0, 2000)}`,
|
|
109
|
+
"",
|
|
110
|
+
"Reply again with ONLY the corrected JSON.",
|
|
111
|
+
].join("\n");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Run a headless turn constrained to a schema, retrying on validation
|
|
116
|
+
* failure. Prints the validated JSON to writeOut; returns the exit code.
|
|
117
|
+
*
|
|
118
|
+
* @param {object} cfg { schemaFile|schema, baseOptions, runHeadless,
|
|
119
|
+
* maxAttempts?, writeOut?, writeErr?, deps? }
|
|
120
|
+
*/
|
|
121
|
+
export async function runJsonSchemaConstrained(cfg = {}) {
|
|
122
|
+
const fs = cfg.deps?.fs || _deps.fs;
|
|
123
|
+
const writeOut = cfg.writeOut || ((s) => process.stdout.write(s));
|
|
124
|
+
const writeErr = cfg.writeErr || ((s) => process.stderr.write(s));
|
|
125
|
+
const maxAttempts = cfg.maxAttempts || MAX_ATTEMPTS;
|
|
126
|
+
|
|
127
|
+
const schema =
|
|
128
|
+
cfg.schema || JSON.parse(fs.readFileSync(cfg.schemaFile, "utf-8"));
|
|
129
|
+
const instruction = buildSchemaInstruction(schema);
|
|
130
|
+
const base = cfg.baseOptions || {};
|
|
131
|
+
|
|
132
|
+
let prompt = base.prompt;
|
|
133
|
+
let lastRaw = "";
|
|
134
|
+
let lastErrors = ["no attempts ran"];
|
|
135
|
+
|
|
136
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
137
|
+
let captured = "";
|
|
138
|
+
const outcome = await cfg.runHeadless(
|
|
139
|
+
{
|
|
140
|
+
...base,
|
|
141
|
+
prompt,
|
|
142
|
+
outputFormat: "text",
|
|
143
|
+
appendSystemPrompt: [base.appendSystemPrompt, instruction]
|
|
144
|
+
.filter(Boolean)
|
|
145
|
+
.join("\n\n"),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
writeOut: (s) => {
|
|
149
|
+
captured += s;
|
|
150
|
+
},
|
|
151
|
+
writeErr,
|
|
152
|
+
},
|
|
153
|
+
);
|
|
154
|
+
const raw = String(outcome?.result ?? captured ?? "").trim() || captured.trim();
|
|
155
|
+
lastRaw = raw;
|
|
156
|
+
const parsed = extractJsonPayload(raw);
|
|
157
|
+
if (parsed.ok) {
|
|
158
|
+
const errors = validateAgainstSchema(parsed.value, schema);
|
|
159
|
+
if (errors.length === 0) {
|
|
160
|
+
writeOut(`${JSON.stringify(parsed.value, null, 2)}\n`);
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
lastErrors = errors;
|
|
164
|
+
} else {
|
|
165
|
+
lastErrors = [parsed.error];
|
|
166
|
+
}
|
|
167
|
+
if (attempt < maxAttempts) {
|
|
168
|
+
writeErr(
|
|
169
|
+
`--json-schema: attempt ${attempt} failed validation (${lastErrors.length} error(s)) — retrying…\n`,
|
|
170
|
+
);
|
|
171
|
+
prompt = buildRetryPrompt(base.prompt, raw, lastErrors);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
writeErr(
|
|
176
|
+
`--json-schema: reply failed validation after ${maxAttempts} attempts:\n${lastErrors
|
|
177
|
+
.map((e) => ` - ${e}`)
|
|
178
|
+
.join("\n")}\nLast reply:\n${lastRaw.slice(0, 1000)}\n`,
|
|
179
|
+
);
|
|
180
|
+
return 1;
|
|
181
|
+
}
|