wicked-crew 0.9.2 → 0.9.3

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 (75) hide show
  1. package/dist/api/delivery-assurance.d.ts +22 -1
  2. package/dist/api/delivery-assurance.d.ts.map +1 -1
  3. package/dist/api/delivery-assurance.js +66 -2
  4. package/dist/api/delivery-assurance.js.map +1 -1
  5. package/dist/api/routes.d.ts +148 -8
  6. package/dist/api/routes.d.ts.map +1 -1
  7. package/dist/api/routes.js +54 -16
  8. package/dist/api/routes.js.map +1 -1
  9. package/dist/api/server.d.ts.map +1 -1
  10. package/dist/api/server.js +31 -31
  11. package/dist/api/server.js.map +1 -1
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +32 -1
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/service.js +1 -1
  16. package/dist/cli/service.js.map +1 -1
  17. package/dist/core/adapter.d.ts +6 -3
  18. package/dist/core/adapter.d.ts.map +1 -1
  19. package/dist/core/adapter.js +36 -17
  20. package/dist/core/adapter.js.map +1 -1
  21. package/dist/core/ado-deliver-helper.d.ts +5 -0
  22. package/dist/core/ado-deliver-helper.d.ts.map +1 -1
  23. package/dist/core/ado-deliver-helper.js +50 -2
  24. package/dist/core/ado-deliver-helper.js.map +1 -1
  25. package/dist/core/deliver-credentials.d.ts +8 -4
  26. package/dist/core/deliver-credentials.d.ts.map +1 -1
  27. package/dist/core/deliver-credentials.js +25 -7
  28. package/dist/core/deliver-credentials.js.map +1 -1
  29. package/dist/core/deliver-text.d.ts +8 -0
  30. package/dist/core/deliver-text.d.ts.map +1 -1
  31. package/dist/core/deliver-text.js +16 -0
  32. package/dist/core/deliver-text.js.map +1 -1
  33. package/dist/core/deliver.d.ts +22 -18
  34. package/dist/core/deliver.d.ts.map +1 -1
  35. package/dist/core/deliver.js +168 -79
  36. package/dist/core/deliver.js.map +1 -1
  37. package/dist/core/types.d.ts +7 -0
  38. package/dist/core/types.d.ts.map +1 -1
  39. package/dist/core/types.js.map +1 -1
  40. package/dist/interactive/chat-events.d.ts +11 -20
  41. package/dist/interactive/chat-events.d.ts.map +1 -1
  42. package/dist/interactive/chat-events.js +69 -108
  43. package/dist/interactive/chat-events.js.map +1 -1
  44. package/dist/interactive/draft-events.d.ts +13 -46
  45. package/dist/interactive/draft-events.d.ts.map +1 -1
  46. package/dist/interactive/draft-events.js +81 -130
  47. package/dist/interactive/draft-events.js.map +1 -1
  48. package/dist/interactive/draft-skill.d.ts +11 -19
  49. package/dist/interactive/draft-skill.d.ts.map +1 -1
  50. package/dist/interactive/draft-skill.js +16 -31
  51. package/dist/interactive/draft-skill.js.map +1 -1
  52. package/dist/interactive/edit-events.d.ts +11 -21
  53. package/dist/interactive/edit-events.d.ts.map +1 -1
  54. package/dist/interactive/edit-events.js +70 -83
  55. package/dist/interactive/edit-events.js.map +1 -1
  56. package/dist/interactive/run-units.d.ts +91 -0
  57. package/dist/interactive/run-units.d.ts.map +1 -0
  58. package/dist/interactive/run-units.js +149 -0
  59. package/dist/interactive/run-units.js.map +1 -0
  60. package/dist/skills/core-closure.d.ts +26 -0
  61. package/dist/skills/core-closure.d.ts.map +1 -1
  62. package/dist/skills/core-closure.js +45 -0
  63. package/dist/skills/core-closure.js.map +1 -1
  64. package/dist/skills/phase-skill-gaps.d.ts +16 -71
  65. package/dist/skills/phase-skill-gaps.d.ts.map +1 -1
  66. package/dist/skills/phase-skill-gaps.js +16 -145
  67. package/dist/skills/phase-skill-gaps.js.map +1 -1
  68. package/dist/studio/assets/{index-BLYKfepE.css → index-BGfFmWw4.css} +1 -1
  69. package/dist/studio/assets/{index-BbXtfDnB.js → index-BMRUMU4X.js} +112 -112
  70. package/dist/studio/editors/wicked-page/editor.json +1 -1
  71. package/dist/studio/editors/wicked-page/index.html +1 -1
  72. package/dist/studio/index.html +2 -2
  73. package/dist/studio/testid-inventory.json +83 -5
  74. package/endpoint-manifest.json +1 -1
  75. package/package.json +3 -3
@@ -8,7 +8,7 @@ import { readFileSync, existsSync } from 'node:fs';
8
8
  import { promises as fsp } from 'node:fs';
9
9
  import { isAbsolute, join, relative, resolve } from 'node:path';
10
10
  import { fileURLToPath } from 'node:url';
11
- import { CampaignsUnsupportedError, ChatUnsupportedError, CoreAdapter, ElicitationUnsupportedError, GovernanceReplayUnsupportedError, PlanLaunchUnsupportedError, SteeringUnsupportedError, addonSupportsReducedAssurance, humanGatePhaseIds, settingsFilePath } from '../core/adapter.js';
11
+ import { CampaignsUnsupportedError, ChatUnsupportedError, CoreAdapter, ElicitationUnsupportedError, GovernanceReplayUnsupportedError, PlanLaunchUnsupportedError, SteeringUnsupportedError, addonSupportsQeOverride, addonSupportsReducedAssurance, humanGatePhaseIds, settingsFilePath } from '../core/adapter.js';
12
12
  import { codeGraphDb, codeGraphErrorStatus, requirementsGraph } from '../core/repoPaths.js';
13
13
  import { resolveCursorUnit } from '../core/cursor.js';
14
14
  import { detectRefusal } from './gate-cache.js';
@@ -49,18 +49,18 @@ import { registerSkillsRoutes } from './skills.js';
49
49
  import { registerMcpRoutes } from './mcp.js';
50
50
  import { McpPolicies } from '../mcp/policies.js';
51
51
  import { disabledSkillsHealth } from '../skills/runtime.js';
52
- import { phaseSkillFindings, withPhaseSkillGaps } from '../skills/phase-skill-gaps.js';
52
+ import { withPhaseSkillGaps } from '../skills/phase-skill-gaps.js';
53
53
  import { STATE_HOME_BLOCKER_CODE, STATE_HOME_REMEDY, isEngineStateHomeRefusal, stateHomeBlockerBody, } from '../projects/state-home-preflight.js';
54
54
  import { BASE_SKILL_POLICIES, BASE_SKILL_REF_SHAPE, baseSkillRemedy } from '../skills/base-skill.js';
55
55
  import { REQUIRED_GARDEN_VERSION } from '../skills/plugin-source.js';
56
56
  import { engineRosterJson, noEligibleSeatBody, parseNoEligibleSeat } from '../core/engine-roster.js';
57
57
  import { launchAssuranceNotice } from '../core/assurance.js';
58
- import { QE_ACCEPTANCE, aggregateReceipt, postHocDeliveryAssurance, qeAcceptanceFromView, qeAcceptanceRefusal, receiptOf, requiresQeAcceptance, unreadableQeAcceptance, } from './delivery-assurance.js';
58
+ import { QE_ACCEPTANCE, QE_PRESETS, aggregateReceipt, postHocDeliveryAssurance, qeAcceptanceFromView, qeAcceptanceRefusal, receiptOf, qeAcceptanceNotRequired, qeDecisionBypasses, qeDecisionOf, unreadableQeAcceptance, } from './delivery-assurance.js';
59
59
  import { ProjectSettingsStore } from '../projects/settings.js';
60
60
  import { isHumanOperator } from './watch-routes.js';
61
61
  import { boundOrigin, InteractiveBridgePool } from '../interactive/bridge-pool.js';
62
62
  import { composeDeliverText, configuredPublicOrigin, extractFollowUps, factsFromRun, reportsFromOutputs, FOLLOW_UPS_MAX, framedDeliverText, runUrlFor, } from '../core/deliver-text.js';
63
- import { deliverRepoFor, deliverTargetView, isGitHubLogin, readDeliverOriginUrl, resolvePullRequest as resolvePullRequestViaGh, unverifiedTreesFrom, } from '../core/deliver.js';
63
+ import { deliverIdentityFor, deliverRepoFor, deliverTargetView, isGitHubLogin, pushIdentityOf, readDeliverOriginUrl, resolvePullRequest as resolvePullRequestViaGh, unverifiedTreesFrom, } from '../core/deliver.js';
64
64
  import { credentialsMissingIn, deliverCredentialsProbe, missingCredentials } from '../core/deliver-credentials.js';
65
65
  import { codebaseArchiveUrl } from './codebase-archive.js';
66
66
  import { registerInteractiveProxy } from '../interactive/proxy-routes.js';
@@ -411,7 +411,16 @@ export const LaunchSchema = z.object({
411
411
  * "full assurance", the same as omitting it: the launcher never chooses for the caller, and a
412
412
  * full-assurance launch on a one-CLI roster is answered with `assuranceNotice` (`core/assurance.ts`). */
413
413
  reducedAssurance: z.boolean().optional(),
414
- }).strict().refine((b) => b.plan === undefined || b.workflow === undefined, {
414
+ /** QE-IN-APP-WORKFLOWS (api-types 0.106.0) — the operator's EXPLICIT skip of a required QE
415
+ * acceptance, with a reason (labelled on the run, every gate and the delivery), or its explicit
416
+ * force (no score waiver). Forwarded only when sent; crew never decides either for the caller,
417
+ * and the engine refuses either on a run whose workflow does not require QE acceptance. */
418
+ skipQeAcceptance: z.object({ reason: z.string().trim().min(1).max(2000) }).strict().optional(),
419
+ forceQeAcceptance: z.boolean().optional(),
420
+ }).strict().refine((b) => b.skipQeAcceptance === undefined || b.forceQeAcceptance !== true, {
421
+ message: 'skipQeAcceptance and forceQeAcceptance are mutually exclusive — skip it with a reason, or force it',
422
+ path: ['forceQeAcceptance'],
423
+ }).refine((b) => b.plan === undefined || b.workflow === undefined, {
415
424
  message: 'plan and workflow are mutually exclusive — a launch carries a plan or names a preset, not both',
416
425
  path: ['plan'],
417
426
  }).refine((b) => b.plan !== undefined || b.deliver !== 'pr' || b.workflow !== undefined, {
@@ -1075,6 +1084,9 @@ runtime = {}) {
1075
1084
  // assurance contract); a one-CLI full-assurance launch answers `assuranceNotice`. A route set
1076
1085
  // that cannot probe the addon reports no capability — never an invented one.
1077
1086
  reducedAssurance: typeof adapter.engineCapabilities === 'function' && addonSupportsReducedAssurance(),
1087
+ // QE-IN-APP-WORKFLOWS: `LaunchRunBody.skipQeAcceptance` / `forceQeAcceptance` reach an addon
1088
+ // that carries the QE decision; never an invented capability.
1089
+ qeAcceptanceOverride: typeof adapter.engineCapabilities === 'function' && addonSupportsQeOverride(),
1078
1090
  };
1079
1091
  // wicked-core#411 / crew#497: the state-home blocker rides the health probe as a WARNING. The
1080
1092
  // daemon still SERVES (status stays ok — studio must load and show the blocker) but refuses to
@@ -1091,14 +1103,11 @@ runtime = {}) {
1091
1103
  // `baseSkill.finding` and `/diagnostics.skills.findings[]` (one surface, no new field;
1092
1104
  // `HealthWarning.kind` is open); status stays ok because the daemon serves and studio must load
1093
1105
  // and show it — exactly the state-home blocker's precedent above.
1094
- // crew#661: a drafting seam that armed WITHOUT its declared skill rides `warnings` as well — its
1095
- // runs proceed degraded, so "status ok, no warnings" would be the silent answer the issue names.
1096
1106
  const warnings = [
1097
1107
  ...(stateHome === null ? [] : stateHome.findings.map((f) => ({ kind: f.kind, severity: f.severity, message: f.message }))),
1098
1108
  ...(baseSkill?.finding ? [{ kind: baseSkill.finding.kind, severity: baseSkill.finding.severity, message: baseSkill.finding.message }] : []),
1099
1109
  // crew#753: a garden older than the minimum is a blocking finding on the first screen too.
1100
1110
  ...[gardenBlocker()].filter((f) => f !== null),
1101
- ...phaseSkillFindings(runtime.phaseSkills?.gaps() ?? []),
1102
1111
  // DES-TEAMING-002 T0: the daemon's bus did not open at boot, so the engine was handed none
1103
1112
  // and runs un-teamed. A daemon-level notice (status stays ok: it serves); the per-run
1104
1113
  // `transport:"none"` record lands with P1.
@@ -1160,9 +1169,9 @@ runtime = {}) {
1160
1169
  // The skills seam's last outcome (skills keystone): published / fallback / blocked /
1161
1170
  // config-error, with the `skills.*` findings the ladder produced — the operator's one
1162
1171
  // read-only answer to "why do launches refuse the snapshot".
1163
- // crew#661: plus every subsystem whose phases ARMED without a declared skill (`phaseSkillGaps`,
1164
- // one `skills.phase-skill` finding each) — the degraded runs' operator-facing record.
1165
- skills: withPhaseSkillGaps(runtime.skills?.health() ?? disabledSkillsHealth(), runtime.phaseSkills),
1172
+ // crew#661's `phaseSkillGaps` stays on the wire, always `[]` since crew#935: no seam arms
1173
+ // without its declared skill (the interactive presets fail such a run instead).
1174
+ skills: withPhaseSkillGaps(runtime.skills?.health() ?? disabledSkillsHealth()),
1166
1175
  // Is the governance evidence LANDING (crew#495): the store, the records on it, the dead
1167
1176
  // letters — with a `governance.deadletter` finding the moment the outbox holds one.
1168
1177
  governance,
@@ -1770,11 +1779,16 @@ runtime = {}) {
1770
1779
  if (b.deliverGate === 'auto') {
1771
1780
  // wicked-core#850 EX-03: a workflow that requires QE acceptance delivers only through the deliver
1772
1781
  // gate, where crew checks the verdict. Unattended delivery would push before anyone could.
1782
+ // QE-IN-APP-WORKFLOWS: an explicit operator skip leaves no verdict to check, so it may. A name
1783
+ // the engine resolves to a built-in preset that requires QE acceptance is judged by that preset
1784
+ // (the engine resolves a preset before any def, so a def of the same name never speaks for it).
1773
1785
  const required = b.workflow !== undefined ? adapter.getWorkflow(b.workflow)?.required_instruments : undefined;
1774
- if (required?.includes(QE_ACCEPTANCE) === true) {
1786
+ const qeRequired = required?.includes(QE_ACCEPTANCE) === true || (b.workflow !== undefined && QE_PRESETS.has(b.workflow));
1787
+ if (qeRequired && b.skipQeAcceptance === undefined) {
1775
1788
  return reply.code(400).send({
1776
1789
  error: `workflow ${b.workflow} requires QE acceptance (required_instruments: qe_acceptance), so it delivers only ` +
1777
- 'through the deliver gate, where the verdict is checked — deliverGate: "auto" cannot apply to it',
1790
+ 'through the deliver gate, where the verdict is checked — deliverGate: "auto" cannot apply to it ' +
1791
+ '(unless the launch explicitly skips QE acceptance with a reason: skipQeAcceptance)',
1778
1792
  });
1779
1793
  }
1780
1794
  input.autoDeliver = true;
@@ -1848,6 +1862,12 @@ runtime = {}) {
1848
1862
  // assurance on anyone's behalf (a one-CLI launch that did not is TOLD so in its answer, below).
1849
1863
  if (b.reducedAssurance === true)
1850
1864
  input.reducedAssurance = true;
1865
+ // QE-IN-APP-WORKFLOWS: the operator's explicit skip (with its reason) or force — forwarded only
1866
+ // when sent, never inferred.
1867
+ if (b.skipQeAcceptance !== undefined)
1868
+ input.skipQeAcceptanceReason = b.skipQeAcceptance.reason;
1869
+ if (b.forceQeAcceptance === true)
1870
+ input.forceQeAcceptance = true;
1851
1871
  // DES-L9 / crew#550 — REVISION: `revisesPr` names an OPEN same-repository pull request whose
1852
1872
  // head branch becomes the run's base (`baseRef`, crew-internal → the engine's
1853
1873
  // `LaunchSpec.base_ref`) and the push target of the composed deliver phase — the PR gains
@@ -1972,6 +1992,9 @@ runtime = {}) {
1972
1992
  // wicked-core#850: the caller's explicit assurance choice (the engine persists the contract
1973
1993
  // on the session; this records WHO waived it).
1974
1994
  ...(b.reducedAssurance !== undefined ? { reducedAssurance: b.reducedAssurance } : {}),
1995
+ // QE-IN-APP-WORKFLOWS: WHO skipped or forced QE acceptance, and why.
1996
+ ...(b.skipQeAcceptance !== undefined ? { skipQeAcceptance: b.skipQeAcceptance } : {}),
1997
+ ...(b.forceQeAcceptance === true ? { forceQeAcceptance: true } : {}),
1975
1998
  // CREW-UX-3: the trail is the durable record of lineage — the retry index (and a
1976
1999
  // restarted daemon's hydrate) reads it back from exactly this entry.
1977
2000
  ...(b.retryOf !== undefined ? { retryOf: b.retryOf } : {}),
@@ -3494,10 +3517,15 @@ runtime = {}) {
3494
3517
  });
3495
3518
  }
3496
3519
  /** EX-03: the run's QE acceptance check when its contract requires `qe_acceptance`; `null` when it
3497
- * does not. A read that fails is a refusal naming why, never a pass. */
3520
+ * does not. A read that fails is a refusal naming why, never a pass. QE-IN-APP-WORKFLOWS: a
3521
+ * decision the score WAIVED or the operator SKIPPED is satisfied without a ledger read and says
3522
+ * which, in the decision's words; only `required` reads the ledger. */
3498
3523
  async function qeAcceptanceCheckFor(run) {
3499
- if (!requiresQeAcceptance(run))
3524
+ const decision = qeDecisionOf(run);
3525
+ if (decision === null)
3500
3526
  return null;
3527
+ if (qeDecisionBypasses(decision))
3528
+ return qeAcceptanceNotRequired(decision);
3501
3529
  try {
3502
3530
  return qeAcceptanceFromView(await acceptanceViewOf(run, { forceDeclared: true }));
3503
3531
  }
@@ -4893,7 +4921,17 @@ runtime = {}) {
4893
4921
  return reply.code(404).send({ error: `Repo ${id} not found` });
4894
4922
  const originUrl = repo.root_path === '' ? null : await readDeliverOriginUrl(repo.root_path);
4895
4923
  // crew#720: the provider credential preflight, so a launch can say "not configured" up front.
4896
- const credentials = await deliverCredentialsProbe(originUrl, process.env);
4924
+ // crew#940: with a push identity configured, only that account's own gh login counts. Settings
4925
+ // that cannot be read leave it unconfigured (GH_ACCOUNT decides), as at launch.
4926
+ let configured = '';
4927
+ try {
4928
+ configured = deliverIdentityFor(await adapter.getSettings(), id).login;
4929
+ }
4930
+ catch {
4931
+ configured = '';
4932
+ }
4933
+ const identity = pushIdentityOf(configured);
4934
+ const credentials = await deliverCredentialsProbe(originUrl, process.env, undefined, identity);
4897
4935
  return reply.send({ repo: repo.id, ...deliverTargetView(originUrl), credentials });
4898
4936
  });
4899
4937
  app.get(`${V}/repos/:id/git-history`, async (req, reply) => {