@zq-silk/yui 0.11.2 → 0.12.0

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.
Files changed (91) hide show
  1. package/ARCHITECTURE.md +23 -4
  2. package/README.md +80 -13
  3. package/dist/cli/commandCatalog.js +30 -5
  4. package/dist/cli.js +105 -43
  5. package/dist/commands/configCommands.js +12 -45
  6. package/dist/commands/executionAuditCommands.js +1 -1
  7. package/dist/commands/jobCommands.js +4 -10
  8. package/dist/commands/projectCommands.js +581 -2
  9. package/dist/commands/taskCommands.js +159 -172
  10. package/dist/commands/taskCompletionGate.js +29 -54
  11. package/dist/commands/taskContextCommand.js +55 -11
  12. package/dist/commands/taskInputCommands.js +8 -5
  13. package/dist/commands/taskIntegrationCommands.js +2 -1
  14. package/dist/commands/taskNextActionCommand.js +56 -6
  15. package/dist/commands/taskOverviewCommand.js +17 -31
  16. package/dist/commands/taskRoleRuntimeStatus.js +24 -0
  17. package/dist/commands/taskWorkspaceCommands.js +5 -2
  18. package/dist/config/configCatalog.js +2 -2
  19. package/dist/config/yuiConfig.js +3 -7
  20. package/dist/context/wakeNotification.js +20 -5
  21. package/dist/controller/agentRuntimeObserver.js +247 -51
  22. package/dist/controller/clientRuntime.js +1 -1
  23. package/dist/controller/controller.js +8 -12
  24. package/dist/controller/fileSchedulerStoreAdapter.js +146 -198
  25. package/dist/controller/runtime.js +3 -3
  26. package/dist/controller/runtimeEventInbox.js +17 -7
  27. package/dist/controller/runtimeEventProcessor.js +12 -19
  28. package/dist/controller/runtimeObservationHook.js +45 -0
  29. package/dist/execution/resourceBroker.js +5 -4
  30. package/dist/executor/agentExecutor.js +4 -4
  31. package/dist/executor/effectiveLaunch.js +8 -48
  32. package/dist/executor/fileRoleLaunchPlanner.js +36 -16
  33. package/dist/executor/workspacePreflightClassification.js +23 -2
  34. package/dist/interaction/operatorPresentation.js +33 -89
  35. package/dist/lifecycle/exactRunTerminalization.js +1 -2
  36. package/dist/lifecycle/taskRoleSessionReset.js +5 -13
  37. package/dist/observability/orchestrationMetrics.js +8 -3
  38. package/dist/profile/agentProfile.js +1 -1
  39. package/dist/release/cliHomeReleaseFence.js +123 -0
  40. package/dist/repository/checkoutSwap.js +61 -0
  41. package/dist/repository/gitWorkspace.js +36 -0
  42. package/dist/repository/project.js +53 -3
  43. package/dist/repository/taskWorkspacePreparer.js +176 -60
  44. package/dist/resources/sqliteResourceRegistry.js +1 -1
  45. package/dist/review/deltaRecheck.js +12 -51
  46. package/dist/review/reviewAcceptance.js +26 -0
  47. package/dist/review/reviewConfig.js +0 -31
  48. package/dist/review/reviewDecision.js +113 -0
  49. package/dist/review/reviewOutcomeClassifier.js +1 -1
  50. package/dist/review/reviewRound.js +1 -1
  51. package/dist/review/reviewerAvailability.js +69 -0
  52. package/dist/runtime/agentDriverObservation.js +24 -10
  53. package/dist/runtime/builtinAgentDrivers.js +4 -3
  54. package/dist/runtime/builtinTranscriptObserver.js +301 -64
  55. package/dist/runtime/builtinTranscriptUsage.js +9 -7
  56. package/dist/runtime/index.js +1 -0
  57. package/dist/runtime/runtimeObservation.js +13 -0
  58. package/dist/runtime/runtimeProjection.js +16 -25
  59. package/dist/runtime/sessionTokenMetrics.js +181 -0
  60. package/dist/runtime/structuredProviderHost.js +7 -1
  61. package/dist/scheduler/activeRoleRunDelivery.js +4 -4
  62. package/dist/scheduler/activeTaskProgress.js +7 -6
  63. package/dist/scheduler/leaderWakeupProcessor.js +3 -5
  64. package/dist/scheduler/operatorEvent.js +34 -0
  65. package/dist/scheduler/operatorInputNotificationProcessor.js +54 -94
  66. package/dist/scheduler/roleRunStall.js +0 -14
  67. package/dist/scheduler/taskExecutionProjection.js +97 -76
  68. package/dist/scheduler/taskObservabilityProjection.js +10 -11
  69. package/dist/storage/migration/productionRegistry.js +467 -0
  70. package/dist/storage/sqliteSchema.js +18 -8
  71. package/dist/storage/sqliteStore.js +61 -21
  72. package/dist/storage/storeRpc.js +0 -1
  73. package/dist/storage/taskStore.js +47 -31
  74. package/dist/storage/upgrade/recordVersions.js +3 -2
  75. package/dist/storage/upgrade/sqliteMigrationTarget.js +30 -8
  76. package/dist/storage/upgrade/sqliteRecordMigrationTarget.js +23 -11
  77. package/dist/storage/upgrade/sqliteStateMigration.js +66 -8
  78. package/dist/task/completionReadiness.js +10 -6
  79. package/dist/task/nextAction.js +82 -24
  80. package/dist/telemetry/sqliteTelemetryStore.js +1 -1
  81. package/dist/web/assets/client/components.js +13 -3
  82. package/dist/web/assets/client/i18n.js +6 -2
  83. package/dist/web/webSnapshot.js +4 -0
  84. package/i18n/README.zh-CN.md +2 -2
  85. package/package.json +1 -1
  86. package/skills/yui-leader/SKILL.md +53 -16
  87. package/skills/yui-operator/SKILL.md +9 -0
  88. package/skills/yui-reviewer/SKILL.md +28 -7
  89. package/dist/context/sessionContextBudget.js +0 -71
  90. package/dist/lifecycle/contextBudgetRollover.js +0 -81
  91. package/dist/scheduler/operatorNotification.js +0 -59
@@ -1,11 +1,11 @@
1
1
  import { mkdirSync, realpathSync } from "node:fs";
2
2
  import { isAbsolute, relative, resolve } from "node:path";
3
3
  import { usageError } from "../errors/cliError.js";
4
- import { DEFAULT_CONTEXT_HARD_TOKENS, DEFAULT_CONTEXT_SOFT_TOKENS, DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_LEADER_NEXT_ACTION_MODE, DEFAULT_LEADER_SEMANTIC_BUDGET_TURNS, DEFAULT_PROVIDER_RETRY_DELAYS_SECONDS, DEFAULT_PROVIDER_RETRY_MAX_WINDOW_SECONDS, DEFAULT_PROVIDER_RETRY_MODE, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, LEADER_NEXT_ACTION_MODES, PROVIDER_RETRY_MODES, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveContextBudget, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetTurns, resolveProviderRetryAdapters, resolveProviderRetryDelaysSeconds, resolveProviderRetryMaxWindowSeconds, resolveProviderRetryMode, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
4
+ import { DEFAULT_AGENT_LAUNCH_INACTIVITY_TIMEOUT_SECONDS, DEFAULT_CONTROLLER_TASK_CONCURRENCY, DEFAULT_DELIVERY_TIMEOUT_SECONDS, DEFAULT_LEADER_NEXT_ACTION_MODE, DEFAULT_LEADER_SEMANTIC_BUDGET_TURNS, DEFAULT_PROVIDER_RETRY_DELAYS_SECONDS, DEFAULT_PROVIDER_RETRY_MAX_WINDOW_SECONDS, DEFAULT_PROVIDER_RETRY_MODE, DEFAULT_RECONCILIATION_INTERVAL_SECONDS, DEFAULT_RESOURCES_GC_MODE, DEFAULT_RESOURCES_QUARANTINE_TTL_HOURS, DEFAULT_TMUX_HISTORY_LIMIT, LEADER_NEXT_ACTION_MODES, PROVIDER_RETRY_MODES, reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveContextBudget, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetTurns, resolveProviderRetryAdapters, resolveProviderRetryDelaysSeconds, resolveProviderRetryMaxWindowSeconds, resolveProviderRetryMode, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
5
5
  import { CONFIG_DEFINITIONS, CONFIG_KEYS, configDefinition, configDefinitionsForDomain } from "../config/configCatalog.js";
6
6
  import { resolveTimeZone } from "../output/timePresentation.js";
7
7
  import { defaultTableWidth, renderTable } from "../output/table.js";
8
- import { DEFAULT_DELTA_RECHECK_MAX_CHANGED_FILES, DEFAULT_DELTA_RECHECK_MAX_CHANGED_LINES, REVIEW_FINDING_LEDGER_MODES, REVIEW_DELTA_RECHECK_MODES, REVIEW_TRIGGERS } from "../review/reviewConfig.js";
8
+ import { REVIEW_FINDING_LEDGER_MODES, REVIEW_TRIGGERS } from "../review/reviewConfig.js";
9
9
  /**
10
10
  * One uniform key model for every durable setting. Each catalog domain uses
11
11
  * the same show/set/clear contract; strategy settings such as `review` and
@@ -23,8 +23,7 @@ const RESOURCES_GC_AUTO_QUARANTINE_SET_USAGE = "Resources config set usage: yui
23
23
  const LEADER_NEXT_ACTION_SET_USAGE = `Workflow config set usage: yui config workflow set leader-next-action <${LEADER_NEXT_ACTION_MODES.join("|")}>.`;
24
24
  const CONTEXT_BUDGET_SET_USAGE = "Workflow config set usage: yui config workflow set context-budget [--soft-tokens <n>] [--hard-tokens <n>].";
25
25
  const REVIEW_SET_USAGE = "Workflow config set usage: yui config workflow set review --role <global-role> --trigger <always|leader|final> "
26
- + "[--finding-ledger <shadow|enforce>] [--delta-recheck <enabled|disabled>] "
27
- + "[--delta-recheck-max-lines <n>] [--delta-recheck-max-files <n>].";
26
+ + "[--finding-ledger <shadow|enforce>].";
28
27
  export function runConfigCommand(domain, args, store) {
29
28
  const keys = configDefinitionsForDomain(domain).map(({ key }) => key);
30
29
  const usage = `${capitalize(domain)} config usage: yui config ${domain} show | yui config ${domain} set <key> <value...> | yui config ${domain} clear <key>.`;
@@ -97,12 +96,7 @@ export function effectiveConfigData(config, domain) {
97
96
  : {
98
97
  roleName: config.review.roleName,
99
98
  trigger: config.review.trigger,
100
- findingLedger: config.review.findingLedger ?? "shadow",
101
- deltaRecheck: config.review.deltaRecheck ?? "disabled",
102
- deltaRecheckMaxChangedLines: config.review.deltaRecheckMaxChangedLines
103
- ?? DEFAULT_DELTA_RECHECK_MAX_CHANGED_LINES,
104
- deltaRecheckMaxChangedFiles: config.review.deltaRecheckMaxChangedFiles
105
- ?? DEFAULT_DELTA_RECHECK_MAX_CHANGED_FILES
99
+ findingLedger: config.review.findingLedger ?? "shadow"
106
100
  },
107
101
  completionInstallations: config.completionInstallations ?? {}
108
102
  };
@@ -175,14 +169,6 @@ function parseReconciliationIntervalSeconds(value) {
175
169
  function parseBooleanConfigValue(value) {
176
170
  return value === "true" ? true : value === "false" ? false : value;
177
171
  }
178
- function parsePositiveIntegerOption(value, usage) {
179
- if (value === undefined)
180
- return undefined;
181
- if (!/^\d+$/.test(value) || Number(value) < 1) {
182
- throw usageError(usage);
183
- }
184
- return Number(value);
185
- }
186
172
  const CONFIG_KEY_HANDLERS = [
187
173
  {
188
174
  key: "default-agent",
@@ -313,10 +299,10 @@ const CONFIG_KEY_HANDLERS = [
313
299
  },
314
300
  {
315
301
  key: "context-budget",
316
- showLabel: "Context budget",
302
+ showLabel: "Legacy context budget (inactive)",
317
303
  showValue: (config) => {
318
304
  const budget = resolveContextBudget(config.contextBudget);
319
- return `soft ${budget.softTokens} / hard ${budget.hardTokens} tokens`;
305
+ return `inactive; legacy soft ${budget.softTokens} / hard ${budget.hardTokens} tokens`;
320
306
  },
321
307
  set(args, store) {
322
308
  if (args.length !== 2 && args.length !== 4)
@@ -343,14 +329,14 @@ const CONFIG_KEY_HANDLERS = [
343
329
  };
344
330
  const resolved = resolveContextBudget({ ...current, ...next });
345
331
  saveConfigKey(store, (config) => ({ ...config, contextBudget: resolved }));
346
- return `Context budget set to soft ${resolved.softTokens} / hard ${resolved.hardTokens} tokens\n`;
332
+ return `Legacy context budget stored as soft ${resolved.softTokens} / hard ${resolved.hardTokens} tokens (inactive)\n`;
347
333
  },
348
334
  clear(store) {
349
335
  saveConfigKey(store, (config) => {
350
336
  const { contextBudget: _removed, ...rest } = config;
351
337
  return rest;
352
338
  });
353
- return `Context budget reset to soft ${DEFAULT_CONTEXT_SOFT_TOKENS} / hard ${DEFAULT_CONTEXT_HARD_TOKENS} tokens\n`;
339
+ return "Legacy context budget cleared; Session Token metrics remain read-only\n";
354
340
  }
355
341
  },
356
342
  {
@@ -696,7 +682,7 @@ const CONFIG_KEY_HANDLERS = [
696
682
  showValue: (config) => (config.review === undefined
697
683
  ? "disabled"
698
684
  : `${config.review.roleName} (${config.review.trigger}; finding ledger: ${config.review.findingLedger ?? "shadow"}`
699
- + `${config.review.deltaRecheck === "enabled" ? "; delta recheck: enabled" : ""})`),
685
+ + ")"),
700
686
  set(args, store) {
701
687
  if (args.length < 4 || args.length % 2 !== 0)
702
688
  throw usageError(REVIEW_SET_USAGE);
@@ -704,8 +690,7 @@ const CONFIG_KEY_HANDLERS = [
704
690
  for (let index = 0; index < args.length; index += 2) {
705
691
  const name = args[index];
706
692
  const value = args[index + 1];
707
- if (!["--role", "--trigger", "--finding-ledger", "--delta-recheck",
708
- "--delta-recheck-max-lines", "--delta-recheck-max-files"].includes(name)
693
+ if (!["--role", "--trigger", "--finding-ledger"].includes(name)
709
694
  || value === undefined
710
695
  || options.has(name)) {
711
696
  throw usageError(REVIEW_SET_USAGE);
@@ -731,33 +716,15 @@ const CONFIG_KEY_HANDLERS = [
731
716
  }
732
717
  findingLedger = rawLedgerMode;
733
718
  }
734
- const rawDeltaRecheck = options.get("--delta-recheck")?.trim();
735
- let deltaRecheck;
736
- if (rawDeltaRecheck !== undefined) {
737
- if (!REVIEW_DELTA_RECHECK_MODES.includes(rawDeltaRecheck)) {
738
- throw usageError(REVIEW_SET_USAGE);
739
- }
740
- deltaRecheck = rawDeltaRecheck;
741
- }
742
- const deltaRecheckMaxChangedLines = parsePositiveIntegerOption(options.get("--delta-recheck-max-lines"), REVIEW_SET_USAGE);
743
- const deltaRecheckMaxChangedFiles = parsePositiveIntegerOption(options.get("--delta-recheck-max-files"), REVIEW_SET_USAGE);
744
719
  saveConfigKey(store, (config) => ({
745
720
  ...config,
746
721
  review: {
747
722
  roleName,
748
723
  trigger,
749
- ...(findingLedger === undefined ? {} : { findingLedger }),
750
- ...(deltaRecheck === undefined ? {} : { deltaRecheck }),
751
- ...(deltaRecheckMaxChangedLines === undefined
752
- ? {}
753
- : { deltaRecheckMaxChangedLines }),
754
- ...(deltaRecheckMaxChangedFiles === undefined
755
- ? {}
756
- : { deltaRecheckMaxChangedFiles })
724
+ ...(findingLedger === undefined ? {} : { findingLedger })
757
725
  }
758
726
  }));
759
- return `Review set to ${roleName} (${trigger}; finding ledger: ${findingLedger ?? "shadow"}; `
760
- + `delta recheck: ${deltaRecheck ?? "disabled"})\n`;
727
+ return `Review set to ${roleName} (${trigger}; finding ledger: ${findingLedger ?? "shadow"})\n`;
761
728
  },
762
729
  clear(store) {
763
730
  saveConfigKey(store, (config) => {
@@ -155,7 +155,7 @@ export function renderExecutionAudit(report, width = defaultTableWidth()) {
155
155
  `Delta-rechecks: ${reviews.deltaRechecks.total} total · `
156
156
  + `${reviews.deltaRechecks.equivalentAndAccepted} accepted · `
157
157
  + `${reviews.deltaRechecks.finding} finding · `
158
- + `${reviews.deltaRechecks.requiresFullReview} escalated to full Review`
158
+ + `${reviews.deltaRechecks.requiresFullReview} requiring Leader decision`
159
159
  ]));
160
160
  }
161
161
  else {
@@ -56,18 +56,14 @@ function collectJobs(store) {
56
56
  });
57
57
  }
58
58
  const failure = store.getLeaderFailure(task.id);
59
- const notification = store.getOperatorNotification(task.id);
60
- const recoveryNotification = notification?.type === "leader-recovery-failed"
61
- ? notification
62
- : null;
63
- if (failure !== null || recoveryNotification !== null) {
59
+ if (failure !== null) {
64
60
  jobs.push({
65
61
  id: `${RECOVERY_PREFIX}${task.id}`,
66
62
  taskId: task.id,
67
63
  kind: "leader-recovery",
68
64
  status: "failed",
69
- detail: failure?.message ?? recoveryNotification?.message ?? "Leader recovery failed.",
70
- updatedAt: failure?.lastFailedAt ?? recoveryNotification?.updatedAt ?? task.updatedAt
65
+ detail: failure.message,
66
+ updatedAt: failure.lastFailedAt
71
67
  });
72
68
  }
73
69
  }
@@ -93,12 +89,10 @@ function retryJob(args, store, options) {
93
89
  if (task.status !== "active") {
94
90
  throw usageError(`Leader recovery can only be retried for an active Task: ${task.id}.`);
95
91
  }
96
- if (tx.getLeaderFailure(task.id) === null
97
- && tx.getOperatorNotification(task.id)?.type !== "leader-recovery-failed") {
92
+ if (tx.getLeaderFailure(task.id) === null) {
98
93
  throw usageError(`Job not found: ${id}.`);
99
94
  }
100
95
  tx.clearLeaderFailure(task.id);
101
- tx.clearOperatorNotification(task.id);
102
96
  enqueueWork(tx, { kind: "role", taskId: task.id, roleName: "leader" }, "recovery-retry", now, [{ type: "task", id: task.id }]);
103
97
  });
104
98
  const target = { kind: "role", taskId, roleName: "leader" };