create-principles-disciple 1.124.1 → 1.124.2

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.
@@ -12,6 +12,7 @@
12
12
  import * as fs from 'node:fs';
13
13
  import * as path from 'node:path';
14
14
  import { SqliteConnection, SqlitePIArtifactStore, SqliteApprovalQueueStore, collectOwnerDecisionFacts, deriveOwnerDecisionCapability, buildOwnerDecisionReview, } from '@principles/core/runtime-v2';
15
+ import { ActivationsConsoleModel } from './ActivationsConsoleModel.js';
15
16
  const GOVERNANCE_TASK_KINDS = new Set(['evaluator', 'rollout_reviewer']);
16
17
  /** tasks.status 合法值(PDTaskStatus)运行时守卫。 */
17
18
  const TASK_STATUSES = new Set(['pending', 'leased', 'succeeded', 'retry_wait', 'failed', 'needs_human_review']);
@@ -242,12 +243,22 @@ export class OwnerDecisionConsoleModel {
242
243
  const shadowRows = db.prepare(`SELECT activation_id, artifact_id, channel, activated_at FROM activations
243
244
  WHERE action = 'code_tool_hook_shadow_activate'
244
245
  AND promoted_at IS NULL AND deactivated_at IS NULL`).all().filter(isRecordRow);
246
+ const activationModel = new ActivationsConsoleModel(this.workspaceDir);
245
247
  for (const row of shadowRows) {
246
248
  const artifactId = typeof row.artifact_id === 'string' ? row.artifact_id : '';
249
+ const activationId = typeof row.activation_id === 'string' ? row.activation_id : '';
250
+ try {
251
+ const review = await activationModel.getOwnerReview(activationId, true);
252
+ if (review.readiness.status !== 'ready' && review.readiness.status !== 'evidence_insufficient')
253
+ continue;
254
+ }
255
+ catch {
256
+ continue;
257
+ }
247
258
  items.push({
248
- reviewKey: `rulecode:${String(row.activation_id ?? '')}`,
259
+ reviewKey: `rulecode:${activationId}`,
249
260
  kind: 'rulecode_decision',
250
- taskId: String(row.activation_id ?? ''),
261
+ taskId: activationId,
251
262
  title: 'RuleCode 影子规则待决',
252
263
  summary: '一条 code_tool_hook 规则处于影子激活期,等待拥有者裁决(提升 / 拒绝)。',
253
264
  reasonCode: 'rulecode_shadow_pending_promotion',
@@ -110,7 +110,7 @@ async function syncWorkspace(name) {
110
110
  }
111
111
  // ── Principles ────────────────────────────────────────────────────────────────
112
112
  async function fetchPrinciples(filter) {
113
- const query = filter && filter !== 'all' ? `?filter=${filter}` : '';
113
+ const query = filter === undefined ? '' : `?filter=${filter}`;
114
114
  return request(`/api/principles${query}`, undefined, validatePrinciplesList);
115
115
  }
116
116
  // Principle detail is deeply nested; for now we accept unvalidated until a
@@ -503,8 +503,8 @@
503
503
  "compareField": "Field",
504
504
  "showMore": "Show more",
505
505
  "showLess": "Show less",
506
- "reviewTitle": "Principle Evolution Timeline",
507
- "reviewSubtitle": "Principle Growth",
506
+ "reviewTitle": "Principle Review",
507
+ "reviewSubtitle": "Review the principles distilled from observed behavior.",
508
508
  "reviewDescription": "These are not cold rules — they are behavioral principles your Agent has distilled from real use.",
509
509
  "metricDeposited": "Deposited Principles",
510
510
  "metricActive": "Active Principles",
@@ -1021,7 +1021,11 @@
1021
1021
  "bearerToken": "Bearer Token",
1022
1022
  "enterAccessToken": "Enter access token",
1023
1023
  "tokenSaved": "Token saved",
1024
+ "tokenSavedRestarting": "Token encrypted and saved; restarting Console to apply it…",
1025
+ "tokenSaveFailed": "Token was not saved. Check desktop encryption and Console status, then retry.",
1026
+ "tokenExternalAttached": "Token saved, but an external Console is still connected.",
1024
1027
  "tokenSessionOnly": "Token is stored in browser session only.",
1028
+ "tokenDesktopStored": "Desktop: encrypted with the Windows system store.",
1025
1029
  "ownerIdentity": {
1026
1030
  "title": "Owner identity",
1027
1031
  "intro": "The Owner identity gates governance decision entry points (RuleCode promotion, emergency pause, etc.). Register to ~/.pd/owner.json (install-level, shared across workspaces). If the PD_OWNER_ID and PD_OWNER_CREDENTIAL_ID environment variables are set together, they take precedence as a pair.",
@@ -503,8 +503,8 @@
503
503
  "compareField": "字段",
504
504
  "showMore": "展开更多",
505
505
  "showLess": "收起",
506
- "reviewTitle": "原则演化轨迹",
507
- "reviewSubtitle": "原则成长",
506
+ "reviewTitle": "原则审查",
507
+ "reviewSubtitle": "审阅从真实行为中沉淀出的原则。",
508
508
  "reviewDescription": "这些不是冰冷的规则,而是智能体在真实使用过程中沉淀下来的行为准则。",
509
509
  "metricDeposited": "沉淀原则",
510
510
  "metricActive": "已生效原则",
@@ -1021,7 +1021,11 @@
1021
1021
  "bearerToken": "Bearer 令牌",
1022
1022
  "enterAccessToken": "输入访问令牌",
1023
1023
  "tokenSaved": "令牌已保存",
1024
+ "tokenSavedRestarting": "令牌已加密保存,正在重启控制台以应用认证…",
1025
+ "tokenSaveFailed": "令牌未保存,请检查桌面加密与控制台状态后重试。",
1026
+ "tokenExternalAttached": "令牌已保存,但当前仍连接着外部控制台。",
1024
1027
  "tokenSessionOnly": "令牌仅存储在浏览器会话中。",
1028
+ "tokenDesktopStored": "桌面版:已通过 Windows 系统加密安全保存。",
1025
1029
  "ownerIdentity": {
1026
1030
  "title": "拥有者身份",
1027
1031
  "intro": "拥有者身份决定治理决策入口(RuleCode 晋升、紧急暂停等)。登记到 ~/.pd/owner.json(安装级,跨工作区生效)。若环境变量 PD_OWNER_ID 与 PD_OWNER_CREDENTIAL_ID 成对设置,则作为一对整体优先生效。",
@@ -74,6 +74,12 @@ export function validateWorkspaceArray(raw) {
74
74
  }
75
75
  return entries;
76
76
  }
77
+ function getCompanionBridge() {
78
+ if (typeof window === "undefined")
79
+ return undefined;
80
+ const candidate = window.pdCompanion;
81
+ return candidate;
82
+ }
77
83
  export function SettingsPage() {
78
84
  const { t } = useTranslation();
79
85
  const { soundEnabled, setSoundEnabled } = useNotifications();
@@ -203,9 +209,37 @@ export function SettingsPage() {
203
209
  const trimmed = tokenInput.trim();
204
210
  if (trimmed.length === 0)
205
211
  return;
206
- setToken(trimmed);
207
- await loadOnboardingFlag();
208
- toast.success(t("pages.settings.tokenSaved"));
212
+ try {
213
+ const companion = getCompanionBridge();
214
+ if (companion !== undefined) {
215
+ const result = await companion.configureConsoleToken(trimmed);
216
+ if (!result.persisted) {
217
+ toast.error(t("pages.settings.tokenSaveFailed"));
218
+ if (result.nextAction)
219
+ toast.info(result.nextAction);
220
+ return;
221
+ }
222
+ if (result.reason === "external_console_attached") {
223
+ toast.info(t("pages.settings.tokenExternalAttached"));
224
+ if (result.nextAction)
225
+ toast.info(result.nextAction, { duration: 8000 });
226
+ }
227
+ else if (result.restartRequested) {
228
+ toast.success(t("pages.settings.tokenSavedRestarting"));
229
+ }
230
+ else {
231
+ toast.success(t("pages.settings.tokenSaved"));
232
+ }
233
+ }
234
+ else {
235
+ toast.success(t("pages.settings.tokenSaved"));
236
+ }
237
+ setToken(trimmed);
238
+ await loadOnboardingFlag();
239
+ }
240
+ catch {
241
+ toast.error(t("pages.settings.tokenSaveFailed"));
242
+ }
209
243
  }, [tokenInput, loadOnboardingFlag, t]);
210
244
  // ── Workspace handlers ─────────────────────────────────────────────────
211
245
  const handleAddWorkspace = useCallback(async () => {
@@ -311,7 +345,9 @@ export function SettingsPage() {
311
345
  return (_jsxs(PageShell, { children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.title") }), _jsxs("div", { className: "mt-6 p-4 bg-panel border border-line rounded-[6px] text-ink-2 text-sm", children: [_jsx("p", { children: t("pages.settings.loadError") }), errorMessage && (_jsx("p", { className: "mt-2 text-ink-4 text-[13px] font-mono", children: errorMessage }))] })] }));
312
346
  }
313
347
  // ── Loaded state ─────────────────────────────────────────────────────────
314
- return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.settings.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-auth", children: [_jsx(SectionTitle, { id: "section-auth", children: t("pages.settings.auth") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("label", { htmlFor: "bearer-token-input", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.bearerToken") }), _jsx("input", { id: "bearer-token-input", type: "password", value: tokenInput, onChange: (e) => setTokenInput(e.target.value), placeholder: t("pages.settings.enterAccessToken"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" }), _jsxs("div", { className: "flex items-center justify-between mt-3", children: [_jsx("button", { onClick: handleSaveToken, disabled: tokenInput.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.save") }), _jsx("span", { className: "text-ink-4 text-[12px]", children: t("pages.settings.tokenSessionOnly") })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-owner-identity", children: [_jsx(SectionTitle, { id: "section-owner-identity", children: t("pages.settings.ownerIdentity.title") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.settings.ownerIdentity.intro") }), ownerIdentity === null ? (_jsx("div", { className: "text-ink-4 text-[12px]", children: t("pages.settings.ownerIdentity.loading") })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-identity-status", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.resolved.source === "none"
348
+ return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.settings.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-auth", children: [_jsx(SectionTitle, { id: "section-auth", children: t("pages.settings.auth") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("label", { htmlFor: "bearer-token-input", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.bearerToken") }), _jsx("input", { id: "bearer-token-input", type: "password", value: tokenInput, onChange: (e) => setTokenInput(e.target.value), placeholder: t("pages.settings.enterAccessToken"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" }), _jsxs("div", { className: "flex items-center justify-between mt-3", children: [_jsx("button", { onClick: handleSaveToken, disabled: tokenInput.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.save") }), _jsx("span", { className: "text-ink-4 text-[12px]", children: getCompanionBridge() === undefined
349
+ ? t("pages.settings.tokenSessionOnly")
350
+ : t("pages.settings.tokenDesktopStored") })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-owner-identity", children: [_jsx(SectionTitle, { id: "section-owner-identity", children: t("pages.settings.ownerIdentity.title") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.settings.ownerIdentity.intro") }), ownerIdentity === null ? (_jsx("div", { className: "text-ink-4 text-[12px]", children: t("pages.settings.ownerIdentity.loading") })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-identity-status", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.resolved.source === "none"
315
351
  ? "bg-amber text-ink"
316
352
  : ownerIdentity.resolved.source === "invalid_env"
317
353
  ? "bg-danger text-paper"