chainlesschain 0.162.9 → 0.162.11
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-BgQaSGlp.js → AIOps-ebtJGjAG.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BhTVuWPn.js → ActionButton-CypkRN-G.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BO1jPw9V.js → Analytics-B2JMlIng.js} +1 -1
- package/src/assets/web-panel/assets/{AppLayout-VX_9bmhs.js → AppLayout-B8QQ4pk7.js} +2 -2
- package/src/assets/web-panel/assets/{Audit-Qvf0oq_Y.js → Audit-BoYaAyFa.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-TjzfYOeC.js → Backup-BfackGZ5.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BLuumXTZ.js → BaseInput-C06FUpDz.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CXrCvi7a.js → Chat-BWxMkBYZ.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox--DOdo_Nz.js → Checkbox-XJMvS3PV.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DAJaraZ7.js → Codegen-CzR462RK.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CezPMM8r.js → Col-BQHpLNCA.js} +1 -1
- package/src/assets/web-panel/assets/{Community-95cmfh28.js → Community-BWRRbJYd.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-GlEOCt_z.js → Compact-BunoKIy9.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Np9rHlBD.js → Compliance-CtJfZctm.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DhobloKt.js → Cowork-ER5-_bod.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-DsvEYSze.js → Cron-C80jYBw1.js} +1 -1
- package/src/assets/web-panel/assets/{Crosschain-D5h0edtx.js → Crosschain-fEMlCNsL.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BgEIvDQh.js → DID-BZpctKmU.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-BQ9z2Vs6.js → Dashboard-RQhZmLi4.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-zDSAIpGs.js → Dropdown-CrpwS84l.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Bhn4LZO4.js → Federation-BEQyZtdR.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-D_NMXINy.js → FormItemContext-DCwvl6Vh.js} +1 -1
- package/src/assets/web-panel/assets/{Git-D6iEbQtW.js → Git-6FihOxMK.js} +1 -1
- package/src/assets/web-panel/assets/{Governance-DXZrVh5v.js → Governance-DlBLHSlJ.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DxgJQVdT.js → Inference-DdSokzV0.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B6iB6jMD.js → KnowledgeGraph-bg8GBHMr.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Bam2v_rb.js → Logs-DdFYdLQ-.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-hmoE5rhf.js → Marketplace-DjnlAeYF.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-XLZTBQ9E.js → McpTools-Czs41YUh.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-C-NXlOEE.js → Memory-CX0b3c8D.js} +1 -1
- package/src/assets/web-panel/assets/{MobileBridge-Xi_Xzm7u.js → MobileBridge-BoFGb9Mm.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BVxyrtNp.js → MobileProjects-B8qQ9H-0.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DY8puwdE.js → Mtc-CRF1NLae.js} +1 -1
- package/src/assets/web-panel/assets/{MtcAudit-DJShrgkU.js → MtcAudit-CdCm70cJ.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-CsNe5Aor.js → Multisig-yoZlpq2Y.js} +1 -1
- package/src/assets/web-panel/assets/{NLProgramming-Me0yNI2U.js → NLProgramming-hFCgqDxJ.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-D_g-p2Tg.js → Notes-DC8pnxs-.js} +1 -1
- package/src/assets/web-panel/assets/{NotificationSettings-DT7K69Vl.js → NotificationSettings-DDVg5Nc8.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-D4hlrApo.js → Organization-0YCtAFMS.js} +1 -1
- package/src/assets/web-panel/assets/{Overflow-BAvaHETK.js → Overflow-DhPLoAdz.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-D570BCdt.js → P2P-BWpuJhkD.js} +1 -1
- package/src/assets/web-panel/assets/{Permissions-5lYj-mLS.js → Permissions-B4IrizO9.js} +1 -1
- package/src/assets/web-panel/assets/{PersonalDataHub-DwFzyawJ.js → PersonalDataHub-ZbziiUr6.js} +1 -1
- package/src/assets/web-panel/assets/{Pipeline-Ce72g3py.js → Pipeline-M65jR6sq.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BsLyD5gE.js → Privacy-BeO8zLup.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CE0ATemT.js → ProjectInit-Ck_ZjrVZ.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectSettings-Cnevuf69.js → ProjectSettings-ijn-97s0.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-Bwe8FTDK.js → Projects-BsNBemeh.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BlN2_n0e.js → Providers-CI7UxKVO.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D90_0612.js → QuickAsk-dE2M1KOB.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CAdqobLh.js → Recommend-B30EgbKS.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-gAeuZfsd.js → Reputation-CV6n7wMx.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Dsz4KRaU.js → Row-DSaoTjlN.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BuTu0HKl.js → RssFeed-_NgBmHaC.js} +1 -1
- package/src/assets/web-panel/assets/{Search-B6jcG3iF.js → Search-B341ooTV.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CcEX8TPI.js → Security-CqCQD8hf.js} +1 -1
- package/src/assets/web-panel/assets/{Services-BBbLFK_e.js → Services-Cju_95rB.js} +1 -1
- package/src/assets/web-panel/assets/{Skeleton-CARhezYN.js → Skeleton-kh_uW22l.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-B9dCFkON.js → Skills-BVRPgciI.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Ds2N-wGY.js → Sla-y-vKFYkI.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-flimA105.js → SpeechSettings-BXJm9zyo.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B1tJs8pr.js → SyncSettings-BmHZR-Kv.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-Cs7_NAOr.js → Tasks-C7zmYW9f.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D3iXQ2gE.js → Templates-DVEG7FdA.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Z6mUmAVT.js → Tenant-CpvjzPCo.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-PIR1l-39.js → Terminal-D_Wpp2iE.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BLjbrTa1.js → Tokens-QBrjdNqi.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CIJzC6pS.js → Trigger-BhR_VEvQ.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-D_-71Gjt.js → Trust-C0xhM2lC.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CwjoYze6.js → UkeySign-BnyP-W3-.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BUvHAwqx.js → VideoEditing-C5Y8MyEK.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Ds-Mgv8V.js → Wallet-DzCPCQNF.js} +1 -1
- package/src/assets/web-panel/assets/{WebAuthn-B1HCLfzA.js → WebAuthn-6X5bLtHU.js} +1 -1
- package/src/assets/web-panel/assets/{WorkflowEditor-BiJ0uOBt.js → WorkflowEditor-ekS27G9f.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CRWoVJL9.js → chat-BikodUwh.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D90H7N7U.js → colors-8yIg5K7E.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C6U27ikN.js → compact-item-MLWo5-GY.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-dR8PtJ-p.js → createContext-nir7ccDv.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-CFe-8hdI.js → hasIn-DxUIHW2P.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cbm7lyTa.js → index-4SFekeAy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DrPvpDNw.js → index-78olN7S9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BWUElbLB.js → index-8qrwsaKy.js} +1 -1
- package/src/assets/web-panel/assets/{index-ml1s2nd5.js → index-9Y0IyfeM.js} +1 -1
- package/src/assets/web-panel/assets/{index-w5t-vMNO.js → index-BSIaRmzU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZopu374.js → index-BURKtxBq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlIs_MhZ.js → index-BcyG-9vV.js} +1 -1
- package/src/assets/web-panel/assets/index-BeA3spHc.js +1 -0
- package/src/assets/web-panel/assets/{index-DOW32kkX.js → index-BgHPrMXP.js} +1 -1
- package/src/assets/web-panel/assets/{index-nrBwYuLT.js → index-BgQtoOHc.js} +1 -1
- package/src/assets/web-panel/assets/{index-gLrDgd8C.js → index-BkMtxzcM.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5fuCdMf.js → index-Bn5VWKW1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKAuW9ip.js → index-Bpa9senE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFbyZ4VS.js → index-C-UB9bYd.js} +1 -1
- package/src/assets/web-panel/assets/{index-rhwSri9e.js → index-CCGf6IJj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DN4iOH17.js → index-C_W1kVtY.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCKkZgvL.js → index-C_Xi08tu.js} +1 -1
- package/src/assets/web-panel/assets/{index-Du2kakr1.js → index-CeX-HLIi.js} +1 -1
- package/src/assets/web-panel/assets/{index-_UAOyaYh.js → index-CfeuuE7v.js} +1 -1
- package/src/assets/web-panel/assets/{index-cMms0yaN.js → index-CkSN2Ki_.js} +1 -1
- package/src/assets/web-panel/assets/{index-zDn5JJTC.js → index-Cp-YnzHN.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5x3uBml.js → index-DDmc4cig.js} +1 -1
- package/src/assets/web-panel/assets/{index-cERDyhbA.js → index-DLiexKJ2.js} +1 -1
- package/src/assets/web-panel/assets/{index-pOwjlfcg.js → index-DOIryna2.js} +1 -1
- package/src/assets/web-panel/assets/{index-WmmdmN6b.js → index-DSjWvxVr.js} +3 -3
- package/src/assets/web-panel/assets/{index-66g2WGdx.js → index-DVLJ1iGu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DibOj-Y8.js → index-DkIon-Gv.js} +1 -1
- package/src/assets/web-panel/assets/{index-l3oIS_5E.js → index-Dl-O2OkQ.js} +1 -1
- package/src/assets/web-panel/assets/index-DoLRjAoc.js +1 -0
- package/src/assets/web-panel/assets/{index-BOOxNqWQ.js → index-Dx5xZmzt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEEu_VP1.js → index-S8mYImvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-D43N1wTf.js → index-SUYLhwZI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSIH2KxQ.js → index-TB5vrA0Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvJ3UZ52.js → index-dgZZAsxo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbQx_BA_.js → index-h05fIj9Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-BL7VlSvq.js → index-hu-wjfWv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE1ONO_z.js → index-q3Lr2UzW.js} +1 -1
- package/src/assets/web-panel/assets/{index-5JpRRs-N.js → index-vVrIg9Jk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCKut9LD.js → index-yfNusVbo.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BYQdbBmy.js → initDefaultProps-xUjF_bq0.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BtpQTgfW.js → motion-B019-Q6h.js} +1 -1
- package/src/assets/web-panel/assets/{move-BXl4Tr-C.js → move-D2XYj_gA.js} +1 -1
- package/src/assets/web-panel/assets/{omit-D83siT_K.js → omit-AIzzlguv.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DAo4jR1m.js → pickAttrs-CRkEQaLs.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BroqhS4u.js → placementArrow-s4kAStH6.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CQ1ZgLXP.js → responsiveObserve-BCsWrTkb.js} +1 -1
- package/src/assets/web-panel/assets/{slide-tkfTw6kp.js → slide-B_Hggtvv.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CGzZbaVH.js → statusUtils-DnNf15VW.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CDEoUvcb.js → styleChecker-CSQdy9SQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Ba76kVFx.js → useFlexGapSupport-Bt-T27Pf.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-B4iO8Fmn.js → useFs-D78PlgeG.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-vHVV16AJ.js → vnode-BTMmpsWu.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DifdtHK7.js → zoom-CwOTbvKc.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/init.js +10 -0
- package/src/commands/notification.js +260 -0
- package/src/commands/pack.js +319 -0
- package/src/commands/persona.js +160 -1
- package/src/index.js +2 -0
- package/src/lib/packer/pkg-config-generator.js +111 -5
- package/src/runtime/agent-core.js +26 -2
- package/src/assets/web-panel/assets/index-EFyvtYMT.js +0 -1
- package/src/assets/web-panel/assets/index-ohea9DVW.js +0 -1
package/src/commands/persona.js
CHANGED
|
@@ -132,6 +132,160 @@ export function registerPersonaCommand(program) {
|
|
|
132
132
|
logger.log(` Role: ${updated.role || "(no role defined)"}`);
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
+
// persona list (Phase 3d)
|
|
136
|
+
persona
|
|
137
|
+
.command("list")
|
|
138
|
+
.description(
|
|
139
|
+
"List named personas registered in config.personas (Phase 3d registry)",
|
|
140
|
+
)
|
|
141
|
+
.option("--json", "Emit JSON instead of human-readable", false)
|
|
142
|
+
.action((options) => {
|
|
143
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
144
|
+
if (!projectRoot) {
|
|
145
|
+
if (options.json) {
|
|
146
|
+
logger.log(
|
|
147
|
+
JSON.stringify({ error: "not in project", code: "NO_PROJECT" }),
|
|
148
|
+
);
|
|
149
|
+
} else {
|
|
150
|
+
logger.error(
|
|
151
|
+
"Not inside a ChainlessChain project. Run `chainlesschain init` first.",
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const config = loadProjectConfig(projectRoot);
|
|
158
|
+
const personas =
|
|
159
|
+
config?.personas && typeof config.personas === "object"
|
|
160
|
+
? config.personas
|
|
161
|
+
: {};
|
|
162
|
+
const active = config?.activePersonaName || null;
|
|
163
|
+
const envName = process.env.CC_PACK_AUTO_PERSONA || null;
|
|
164
|
+
|
|
165
|
+
if (options.json) {
|
|
166
|
+
logger.log(
|
|
167
|
+
JSON.stringify(
|
|
168
|
+
{
|
|
169
|
+
activePersonaName: active,
|
|
170
|
+
envPersona: envName,
|
|
171
|
+
personas: Object.fromEntries(
|
|
172
|
+
Object.entries(personas).map(([k, v]) => [
|
|
173
|
+
k,
|
|
174
|
+
{ name: v?.name || null, role: v?.role || null },
|
|
175
|
+
]),
|
|
176
|
+
),
|
|
177
|
+
hasLegacyInlinePersona: Boolean(config?.persona),
|
|
178
|
+
},
|
|
179
|
+
null,
|
|
180
|
+
2,
|
|
181
|
+
),
|
|
182
|
+
);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (Object.keys(personas).length === 0) {
|
|
187
|
+
logger.log("No named personas registered.");
|
|
188
|
+
if (config?.persona) {
|
|
189
|
+
logger.log(
|
|
190
|
+
chalk.dim(
|
|
191
|
+
" (Legacy inline `config.persona` is set; it activates as the default.)",
|
|
192
|
+
),
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
logger.log(
|
|
196
|
+
`\nAdd one via \`config.personas.<name>\` or by re-running \`cc init -t <template>\` (medical-triage / agriculture-expert / etc.).`,
|
|
197
|
+
);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
logger.log(chalk.bold("Registered personas:"));
|
|
202
|
+
for (const [k, v] of Object.entries(personas)) {
|
|
203
|
+
const marker =
|
|
204
|
+
k === envName
|
|
205
|
+
? chalk.green(" ← CC_PACK_AUTO_PERSONA")
|
|
206
|
+
: k === active
|
|
207
|
+
? chalk.cyan(" ← active")
|
|
208
|
+
: "";
|
|
209
|
+
logger.log(` ${chalk.cyan(k)}${marker}`);
|
|
210
|
+
if (v?.name) logger.log(` name: ${v.name}`);
|
|
211
|
+
if (v?.role) {
|
|
212
|
+
const oneLine = String(v.role).split("\n")[0].slice(0, 80);
|
|
213
|
+
logger.log(chalk.dim(` role: ${oneLine}`));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (envName && !personas[envName]) {
|
|
217
|
+
logger.log(
|
|
218
|
+
chalk.yellow(
|
|
219
|
+
`\n Warning: CC_PACK_AUTO_PERSONA="${envName}" does not match any registered persona.`,
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// persona activate (Phase 3d)
|
|
226
|
+
persona
|
|
227
|
+
.command("activate <name>")
|
|
228
|
+
.description(
|
|
229
|
+
"Activate a named persona from config.personas (Phase 3d; equivalent to `cc skill enable` for persona-category skills)",
|
|
230
|
+
)
|
|
231
|
+
.action((name) => {
|
|
232
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
233
|
+
if (!projectRoot) {
|
|
234
|
+
logger.error(
|
|
235
|
+
"Not inside a ChainlessChain project. Run `chainlesschain init` first.",
|
|
236
|
+
);
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const configPath = path.join(
|
|
241
|
+
projectRoot,
|
|
242
|
+
".chainlesschain",
|
|
243
|
+
"config.json",
|
|
244
|
+
);
|
|
245
|
+
let config;
|
|
246
|
+
try {
|
|
247
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
248
|
+
} catch {
|
|
249
|
+
logger.error("Failed to read config.json");
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const personas =
|
|
254
|
+
config.personas && typeof config.personas === "object"
|
|
255
|
+
? config.personas
|
|
256
|
+
: {};
|
|
257
|
+
const target = personas[name];
|
|
258
|
+
if (!target) {
|
|
259
|
+
const available = Object.keys(personas);
|
|
260
|
+
logger.error(`No persona named "${name}" in config.personas.`);
|
|
261
|
+
if (available.length > 0) {
|
|
262
|
+
logger.log(`Available: ${chalk.cyan(available.join(", "))}`);
|
|
263
|
+
} else {
|
|
264
|
+
logger.log(
|
|
265
|
+
chalk.dim(
|
|
266
|
+
" (No named personas registered. See `cc persona list` for details.)",
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
config.activePersonaName = name;
|
|
274
|
+
// Denormalize so `_loadProjectPersona`'s legacy `config.persona` read
|
|
275
|
+
// path also sees the activation. Single source of truth is
|
|
276
|
+
// `activePersonaName`, but the inline copy keeps the resolver
|
|
277
|
+
// backward-compatible without forcing a config-version bump.
|
|
278
|
+
config.persona = target;
|
|
279
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
280
|
+
|
|
281
|
+
logger.success(`Activated persona "${chalk.cyan(name)}".`);
|
|
282
|
+
logger.log(` Display name: ${target.name || "(unnamed)"}`);
|
|
283
|
+
if (target.role) {
|
|
284
|
+
const oneLine = String(target.role).split("\n")[0].slice(0, 80);
|
|
285
|
+
logger.log(chalk.dim(` Role: ${oneLine}`));
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
135
289
|
// persona reset
|
|
136
290
|
persona
|
|
137
291
|
.command("reset")
|
|
@@ -160,12 +314,17 @@ export function registerPersonaCommand(program) {
|
|
|
160
314
|
process.exit(1);
|
|
161
315
|
}
|
|
162
316
|
|
|
163
|
-
if (!config.persona) {
|
|
317
|
+
if (!config.persona && !config.activePersonaName) {
|
|
164
318
|
logger.log("No persona configured. Nothing to reset.");
|
|
165
319
|
return;
|
|
166
320
|
}
|
|
167
321
|
|
|
168
322
|
delete config.persona;
|
|
323
|
+
// Phase 3d: also clear the active-name pointer so _loadProjectPersona
|
|
324
|
+
// doesn't re-resolve through config.personas[activeName]. The personas
|
|
325
|
+
// registry itself is preserved — user can re-activate with `cc persona
|
|
326
|
+
// activate <name>`.
|
|
327
|
+
delete config.activePersonaName;
|
|
169
328
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
170
329
|
logger.success(
|
|
171
330
|
"Persona removed. The default coding assistant will be used.",
|
package/src/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { registerConfigCommand } from "./commands/config.js";
|
|
|
9
9
|
import { registerUpdateCommand } from "./commands/update.js";
|
|
10
10
|
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
11
11
|
import { registerPairCommand } from "./commands/pair.js";
|
|
12
|
+
import { registerNotificationCommand } from "./commands/notification.js";
|
|
12
13
|
import { registerDbCommand } from "./commands/db.js";
|
|
13
14
|
import { registerNoteCommand } from "./commands/note.js";
|
|
14
15
|
import { registerChatCommand } from "./commands/chat.js";
|
|
@@ -395,6 +396,7 @@ export function createProgram(opts = {}) {
|
|
|
395
396
|
registerUpdateCommand(program);
|
|
396
397
|
registerDoctorCommand(program);
|
|
397
398
|
registerPairCommand(program);
|
|
399
|
+
registerNotificationCommand(program);
|
|
398
400
|
|
|
399
401
|
// Headless commands
|
|
400
402
|
registerDbCommand(program);
|
|
@@ -184,35 +184,110 @@ export function generatePkgConfig(ctx) {
|
|
|
184
184
|
"// check-update`) can read packedCliVersion / updateManifestUrl without",
|
|
185
185
|
"// importing from the packer. No-op in CLI-only builds outside pkg.",
|
|
186
186
|
"globalThis.BAKED = BAKED;",
|
|
187
|
+
"// .env sidecar parser (per design §13 #4). Returns a flat KEY=VALUE",
|
|
188
|
+
"// dict; missing file / unreadable -> {}. Skips blank lines, '#' comments,",
|
|
189
|
+
"// and BOM. Strips matching single/double quote pairs but leaves inner",
|
|
190
|
+
"// content untouched (no escape-sequence interpretation — power users who",
|
|
191
|
+
"// need that can set the var from their shell, which wins anyway).",
|
|
192
|
+
"function _loadDotenv(filePath) {",
|
|
193
|
+
" try {",
|
|
194
|
+
" if (!filePath || !fs.existsSync(filePath)) return {};",
|
|
195
|
+
" const body = fs.readFileSync(filePath, 'utf-8').replace(/^\\uFEFF/, '');",
|
|
196
|
+
" const out = {};",
|
|
197
|
+
" for (const rawLine of body.split(/\\r?\\n/)) {",
|
|
198
|
+
" const line = rawLine.trim();",
|
|
199
|
+
" if (!line || line.startsWith('#')) continue;",
|
|
200
|
+
" const eq = line.indexOf('=');",
|
|
201
|
+
" if (eq <= 0) continue;",
|
|
202
|
+
" const key = line.slice(0, eq).trim();",
|
|
203
|
+
" let val = line.slice(eq + 1).trim();",
|
|
204
|
+
" if (val.length >= 2 &&",
|
|
205
|
+
" ((val.startsWith('\"') && val.endsWith('\"')) ||",
|
|
206
|
+
' (val.startsWith("\'") && val.endsWith("\'")))) {',
|
|
207
|
+
" val = val.slice(1, -1);",
|
|
208
|
+
" }",
|
|
209
|
+
" out[key] = val;",
|
|
210
|
+
" }",
|
|
211
|
+
" return out;",
|
|
212
|
+
" } catch { return {}; }",
|
|
213
|
+
"}",
|
|
214
|
+
"// Schema-aware deep-merge: bundled (base) values fill in missing keys,",
|
|
215
|
+
"// existing user values win. Used only for .chainlesschain/config.json so",
|
|
216
|
+
"// new exe schema fields land without clobbering user edits.",
|
|
217
|
+
"function _deepMerge(base, override) {",
|
|
218
|
+
" if (override === null || typeof override !== 'object' || Array.isArray(override)) return override;",
|
|
219
|
+
" if (base === null || typeof base !== 'object' || Array.isArray(base)) return override;",
|
|
220
|
+
" const out = { ...base };",
|
|
221
|
+
" for (const k of Object.keys(override)) {",
|
|
222
|
+
" out[k] = (k in base) ? _deepMerge(base[k], override[k]) : override[k];",
|
|
223
|
+
" }",
|
|
224
|
+
" return out;",
|
|
225
|
+
"}",
|
|
187
226
|
"// Merge-copy helper: copies src tree into dest, skipping files that",
|
|
188
227
|
"// already exist (preserves user modifications). Used only in project mode.",
|
|
189
|
-
"
|
|
228
|
+
"// Special case: top-level config.json gets deep-merged (user values win,",
|
|
229
|
+
"// bundled supplies new schema fields).",
|
|
230
|
+
"function copyRecursiveMerge(src, dest, rootSrc) {",
|
|
231
|
+
" if (rootSrc === undefined) rootSrc = src;",
|
|
190
232
|
" if (!fs.existsSync(src)) return;",
|
|
191
233
|
" fs.mkdirSync(dest, { recursive: true });",
|
|
192
234
|
" for (const e of fs.readdirSync(src, { withFileTypes: true })) {",
|
|
193
235
|
" const sp = path.join(src, e.name), dp = path.join(dest, e.name);",
|
|
194
|
-
" if (e.isDirectory()) { copyRecursiveMerge(sp, dp); }",
|
|
236
|
+
" if (e.isDirectory()) { copyRecursiveMerge(sp, dp, rootSrc); }",
|
|
195
237
|
" else if (!fs.existsSync(dp)) { fs.copyFileSync(sp, dp); }",
|
|
196
|
-
" else {
|
|
238
|
+
" else {",
|
|
239
|
+
" const _rel = path.relative(rootSrc, sp).replace(/\\\\/g, '/');",
|
|
240
|
+
" if (_rel === 'config.json') {",
|
|
241
|
+
" try {",
|
|
242
|
+
" const _userCfg = JSON.parse(fs.readFileSync(dp, 'utf-8'));",
|
|
243
|
+
" const _newCfg = JSON.parse(fs.readFileSync(sp, 'utf-8'));",
|
|
244
|
+
" const _merged = _deepMerge(_newCfg, _userCfg);",
|
|
245
|
+
" fs.writeFileSync(dp, JSON.stringify(_merged, null, 2), 'utf-8');",
|
|
246
|
+
" } catch (err) { console.warn('[cc-pack] config.json merge failed, keeping existing:', dp, err && err.message); }",
|
|
247
|
+
" } else {",
|
|
248
|
+
" console.warn('[cc-pack] Keeping existing file (user-modified):', dp);",
|
|
249
|
+
" }",
|
|
250
|
+
" }",
|
|
197
251
|
" }",
|
|
198
252
|
"}",
|
|
199
253
|
"// ── Project mode: materialize bundled .chainlesschain/ to user-data dir ──",
|
|
200
254
|
"// BAKED.projectMode is absent (falsy) in CLI-only builds — entire block skipped.",
|
|
201
255
|
"if (BAKED.projectMode) {",
|
|
256
|
+
" // Per design §9: prefer %APPDATA% on Windows (Roaming, ~260-char-safe);",
|
|
257
|
+
" // fall back to ~ on other platforms or when APPDATA is unset.",
|
|
258
|
+
" const _baseDir = (process.platform === 'win32' && process.env.APPDATA)",
|
|
259
|
+
" ? process.env.APPDATA",
|
|
260
|
+
" : os.homedir();",
|
|
261
|
+
" // SHA-16 (64-bit entropy) per design §4.3 — prior SHA-8 had 32-bit entropy",
|
|
262
|
+
" // which is too narrow for multi-project + multi-version coexistence.",
|
|
202
263
|
" const _userDataDir = path.join(",
|
|
203
|
-
"
|
|
204
|
-
" `${BAKED.projectName}-${BAKED.projectConfigSha.slice(0,
|
|
264
|
+
" _baseDir, '.chainlesschain-projects',",
|
|
265
|
+
" `${BAKED.projectName}-${BAKED.projectConfigSha.slice(0, 16)}`,",
|
|
205
266
|
" );",
|
|
206
267
|
" const _markerFile = path.join(_userDataDir, '.chainlesschain', '.pack-version');",
|
|
268
|
+
" const _lockFile = path.join(_userDataDir, '.chainlesschain', '.materialize.lock');",
|
|
207
269
|
" const _needsMaterialize =",
|
|
208
270
|
" BAKED.forceRefreshOnLaunch ||",
|
|
209
271
|
" !fs.existsSync(_markerFile) ||",
|
|
210
272
|
" fs.readFileSync(_markerFile, 'utf8').trim() !== BAKED.projectConfigSha;",
|
|
273
|
+
" // Concurrent-materialize protection: only the first instance acquires the",
|
|
274
|
+
" // lock and does the copy. Other instances skip silently — the marker file",
|
|
275
|
+
" // will already be written by the time they get to use the dir.",
|
|
276
|
+
" let _lockFd = null;",
|
|
211
277
|
" if (_needsMaterialize) {",
|
|
278
|
+
" try {",
|
|
279
|
+
" fs.mkdirSync(path.dirname(_lockFile), { recursive: true });",
|
|
280
|
+
" _lockFd = fs.openSync(_lockFile, 'wx');",
|
|
281
|
+
" } catch { /* another instance holds the lock */ }",
|
|
282
|
+
" }",
|
|
283
|
+
" if (_needsMaterialize && _lockFd !== null) {",
|
|
212
284
|
" copyRecursiveMerge(BAKED.projectBundledDir, path.join(_userDataDir, '.chainlesschain'));",
|
|
213
285
|
" fs.mkdirSync(path.dirname(_markerFile), { recursive: true });",
|
|
214
286
|
" fs.writeFileSync(_markerFile, BAKED.projectConfigSha, 'utf8');",
|
|
215
287
|
" }",
|
|
288
|
+
" if (_lockFd !== null) {",
|
|
289
|
+
" try { fs.closeSync(_lockFd); fs.unlinkSync(_lockFile); } catch { /* best-effort */ }",
|
|
290
|
+
" }",
|
|
216
291
|
" process.env.CC_PROJECT_ROOT = _userDataDir;",
|
|
217
292
|
" if (BAKED.projectAllowedSubcommands) {",
|
|
218
293
|
" process.env.CC_PROJECT_ALLOWED_SUBCOMMANDS = BAKED.projectAllowedSubcommands.join(',');",
|
|
@@ -223,6 +298,25 @@ export function generatePkgConfig(ctx) {
|
|
|
223
298
|
" process.env.CC_PACK_AUTO_PERSONA = BAKED.projectAutoPersona;",
|
|
224
299
|
" }",
|
|
225
300
|
"}",
|
|
301
|
+
"// Phase 3f: .env sidecar loader (per design §13 #4 + §9 LLM API keys).",
|
|
302
|
+
"// Priority (highest to lowest): explicit process.env (set in shell),",
|
|
303
|
+
"// <CC_PROJECT_ROOT>/.env, <exePath dir>/.env. We snapshot the original",
|
|
304
|
+
"// process.env keys before reading so neither .env can mask a user's",
|
|
305
|
+
"// shell-level export. The userDataDir .env wins over exePath dir when",
|
|
306
|
+
"// both define the same key because we apply it second.",
|
|
307
|
+
"{",
|
|
308
|
+
" const _origEnvKeys = new Set(Object.keys(process.env));",
|
|
309
|
+
" const _exeEnv = _loadDotenv(path.join(path.dirname(process.execPath), '.env'));",
|
|
310
|
+
" const _userEnv = process.env.CC_PROJECT_ROOT",
|
|
311
|
+
" ? _loadDotenv(path.join(process.env.CC_PROJECT_ROOT, '.env'))",
|
|
312
|
+
" : {};",
|
|
313
|
+
" for (const _k of Object.keys(_exeEnv)) {",
|
|
314
|
+
" if (!_origEnvKeys.has(_k)) process.env[_k] = _exeEnv[_k];",
|
|
315
|
+
" }",
|
|
316
|
+
" for (const _k of Object.keys(_userEnv)) {",
|
|
317
|
+
" if (!_origEnvKeys.has(_k)) process.env[_k] = _userEnv[_k];",
|
|
318
|
+
" }",
|
|
319
|
+
"}",
|
|
226
320
|
"// Double-click from Explorer arrives with no subcommand — without",
|
|
227
321
|
"// this default, commander prints help and exits, which looks like",
|
|
228
322
|
"// a black console 'flash and close'. In project mode the baked",
|
|
@@ -231,6 +325,18 @@ export function generatePkgConfig(ctx) {
|
|
|
231
325
|
"const _hasSub = _rest.some((a) => a && !a.startsWith('-'));",
|
|
232
326
|
"const _argSet = new Set(_rest);",
|
|
233
327
|
"const _hasFlag = (...names) => names.some((n) => _argSet.has(n));",
|
|
328
|
+
"// Phase 3f: --version --json short-circuit (per design §13 #3). Plain",
|
|
329
|
+
"// --version goes through commander; the --json combo emits a structured",
|
|
330
|
+
"// payload with cli + (in project mode) project name/sha. We intercept",
|
|
331
|
+
"// before commander.parse so the JSON is the only thing on stdout.",
|
|
332
|
+
"if (_hasFlag('-v', '--version') && _hasFlag('--json')) {",
|
|
333
|
+
" const _vOut = { cli: BAKED.packedCliVersion || 'unknown' };",
|
|
334
|
+
" if (BAKED.projectMode) {",
|
|
335
|
+
" _vOut.project = { name: BAKED.projectName, sha: BAKED.projectConfigSha };",
|
|
336
|
+
" }",
|
|
337
|
+
" console.log(JSON.stringify(_vOut));",
|
|
338
|
+
" process.exit(0);",
|
|
339
|
+
"}",
|
|
234
340
|
"// Commander short-circuits --version / --help before running any",
|
|
235
341
|
"// command — don't pollute their stdout with the token banner and",
|
|
236
342
|
"// baked defaults they'd never see anyway.",
|
|
@@ -255,7 +255,18 @@ Current working directory: ${cwd || process.cwd()}`;
|
|
|
255
255
|
// ─── Persona support ─────────────────────────────────────────────────────
|
|
256
256
|
|
|
257
257
|
/**
|
|
258
|
-
* Load persona configuration from project config.json
|
|
258
|
+
* Load persona configuration from project config.json.
|
|
259
|
+
*
|
|
260
|
+
* Resolution order (highest priority first):
|
|
261
|
+
* 1. CC_PACK_AUTO_PERSONA env var → config.personas[<env>] if present
|
|
262
|
+
* (set by `cc pack --project` packed exe at boot, per Phase 3f; the
|
|
263
|
+
* Phase 3d resolver lives here so packaged products actually activate
|
|
264
|
+
* their bundled persona at runtime)
|
|
265
|
+
* 2. config.activePersonaName → config.personas[<name>] if present
|
|
266
|
+
* (set by `cc persona activate <name>`)
|
|
267
|
+
* 3. config.persona (the legacy inline single-persona shape; still the
|
|
268
|
+
* common case for projects created via `cc init`)
|
|
269
|
+
*
|
|
259
270
|
* @param {string} cwd - working directory
|
|
260
271
|
* @returns {object|null} persona object or null
|
|
261
272
|
*/
|
|
@@ -264,7 +275,20 @@ function _loadProjectPersona(cwd) {
|
|
|
264
275
|
const projectRoot = findProjectRoot(cwd || process.cwd());
|
|
265
276
|
if (!projectRoot) return null;
|
|
266
277
|
const config = loadProjectConfig(projectRoot);
|
|
267
|
-
|
|
278
|
+
if (!config) return null;
|
|
279
|
+
const personas =
|
|
280
|
+
config.personas && typeof config.personas === "object"
|
|
281
|
+
? config.personas
|
|
282
|
+
: null;
|
|
283
|
+
const envName = process.env.CC_PACK_AUTO_PERSONA;
|
|
284
|
+
if (envName && personas && personas[envName]) {
|
|
285
|
+
return personas[envName];
|
|
286
|
+
}
|
|
287
|
+
const activeName = config.activePersonaName;
|
|
288
|
+
if (activeName && personas && personas[activeName]) {
|
|
289
|
+
return personas[activeName];
|
|
290
|
+
}
|
|
291
|
+
return config.persona || null;
|
|
268
292
|
} catch {
|
|
269
293
|
return null;
|
|
270
294
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-CezPMM8r.js";import{S as t}from"./index-WmmdmN6b.js";import"./index-BbQx_BA_.js";import"./vendor-M5lGV-wr.js";import"./icons-CLQTHa5-.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-Dsz4KRaU.js";import{S as t}from"./index-WmmdmN6b.js";import"./responsiveObserve-CQ1ZgLXP.js";import"./vendor-M5lGV-wr.js";import"./useFlexGapSupport-Ba76kVFx.js";import"./styleChecker-CDEoUvcb.js";import"./index-BbQx_BA_.js";import"./icons-CLQTHa5-.js";const l=t(o);export{l as default};
|