@aviaratech/ai-delivery 0.3.22 → 0.3.24
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/CONTRIBUTING.md +9 -0
- package/README.md +77 -442
- package/dist/agent.d.ts +5 -11
- package/dist/agent.js +4 -8
- package/dist/agent.js.map +1 -1
- package/dist/cli.js +59 -107
- package/dist/cli.js.map +1 -1
- package/dist/config/deliveryConfig.d.ts +44 -55
- package/dist/config/deliveryConfig.js +85 -88
- package/dist/config/deliveryConfig.js.map +1 -1
- package/dist/config/deliveryConfig.test.js +13 -5
- package/dist/config/deliveryConfig.test.js.map +1 -1
- package/dist/delivery/common.d.ts +4 -1
- package/dist/delivery/common.js +56 -8
- package/dist/delivery/common.js.map +1 -1
- package/dist/delivery/delivery.test.js +2 -3
- package/dist/delivery/delivery.test.js.map +1 -1
- package/dist/delivery/index.d.ts +0 -6
- package/dist/delivery/index.js +0 -3
- package/dist/delivery/index.js.map +1 -1
- package/dist/delivery/legacy.d.ts +8 -0
- package/dist/delivery/legacy.js +5 -0
- package/dist/delivery/legacy.js.map +1 -0
- package/dist/delivery/policy.js +2 -13
- package/dist/delivery/policy.js.map +1 -1
- package/dist/delivery/stage.d.ts +6 -0
- package/dist/delivery/stage.js +11 -2
- package/dist/delivery/stage.js.map +1 -1
- package/dist/directoryIndependent.test.d.ts +1 -0
- package/dist/directoryIndependent.test.js +262 -0
- package/dist/directoryIndependent.test.js.map +1 -0
- package/dist/dispatch.d.ts +29 -3
- package/dist/dispatch.js +160 -457
- package/dist/dispatch.js.map +1 -1
- package/dist/genericCompatibility.test.js +0 -35
- package/dist/genericCompatibility.test.js.map +1 -1
- package/dist/git.js +10 -3
- package/dist/git.js.map +1 -1
- package/dist/gitProcess.d.ts +6 -0
- package/dist/gitProcess.js +56 -0
- package/dist/gitProcess.js.map +1 -0
- package/dist/github/discovery.d.ts +1 -0
- package/dist/github/discovery.js +1 -1
- package/dist/github/discovery.js.map +1 -1
- package/dist/github/discovery.test.js +25 -20
- package/dist/github/discovery.test.js.map +1 -1
- package/dist/github/nativeIssueMetadata.d.ts +2 -2
- package/dist/github/nativeIssueMetadata.js.map +1 -1
- package/dist/github/projectDelivery.d.ts +1 -1
- package/dist/github/projectDelivery.js.map +1 -1
- package/dist/github/repo.d.ts +7 -1
- package/dist/github/repo.js +58 -2
- package/dist/github/repo.js.map +1 -1
- package/dist/issue.d.ts +11 -6
- package/dist/issue.js +136 -319
- package/dist/issue.js.map +1 -1
- package/dist/issueJournal.d.ts +1 -1
- package/dist/lifecycle.test.js +40 -7371
- package/dist/lifecycle.test.js.map +1 -1
- package/dist/logger.js +4 -4
- package/dist/logger.js.map +1 -1
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools.d.ts +27 -42
- package/dist/mcp/tools.js +34 -42
- package/dist/mcp/tools.js.map +1 -1
- package/dist/pluginInstaller.d.ts +51 -0
- package/dist/pluginInstaller.js +774 -0
- package/dist/pluginInstaller.js.map +1 -0
- package/dist/pluginInstaller.test.d.ts +1 -0
- package/dist/pluginInstaller.test.js +543 -0
- package/dist/pluginInstaller.test.js.map +1 -0
- package/dist/pluginPackaging.test.d.ts +1 -0
- package/dist/pluginPackaging.test.js +245 -0
- package/dist/pluginPackaging.test.js.map +1 -0
- package/dist/pr.d.ts +66 -114
- package/dist/pr.js +288 -1108
- package/dist/pr.js.map +1 -1
- package/dist/pr.test.js +295 -237
- package/dist/pr.test.js.map +1 -1
- package/dist/releaseReconciliation.test.d.ts +1 -0
- package/dist/releaseReconciliation.test.js +314 -0
- package/dist/releaseReconciliation.test.js.map +1 -0
- package/dist/review.d.ts +37 -7
- package/dist/review.js +106 -45
- package/dist/review.js.map +1 -1
- package/dist/review.test.js +30 -71
- package/dist/review.test.js.map +1 -1
- package/dist/services/agentReadinessService.d.ts +1 -1
- package/dist/services/agentReadinessService.js +2 -0
- package/dist/services/agentReadinessService.js.map +1 -1
- package/dist/services/deliveryAdmission.d.ts +4 -4
- package/dist/services/deliveryAdmission.js.map +1 -1
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +71 -10
- package/dist/setup.js.map +1 -1
- package/dist/setup.test.js +594 -204
- package/dist/setup.test.js.map +1 -1
- package/dist/start.test.d.ts +1 -0
- package/dist/start.test.js +72 -0
- package/dist/start.test.js.map +1 -0
- package/dist/stdoutRegression.test.d.ts +1 -0
- package/dist/stdoutRegression.test.js +326 -0
- package/dist/stdoutRegression.test.js.map +1 -0
- package/dist/verification.d.ts +62 -27
- package/dist/verification.js +172 -1337
- package/dist/verification.js.map +1 -1
- package/dist/worktree.d.ts +1 -31
- package/dist/worktree.js +5 -200
- package/dist/worktree.js.map +1 -1
- package/dist/worktreeTransition.d.ts +1 -1
- package/dist/worktreeTransition.js +10 -5
- package/dist/worktreeTransition.js.map +1 -1
- package/dist/worktreeTransition.test.js +2 -3
- package/dist/worktreeTransition.test.js.map +1 -1
- package/package.json +4 -4
- package/plugins/ai-delivery/.claude-plugin/plugin.json +6 -1
- package/plugins/ai-delivery/LICENSE +21 -0
- package/plugins/ai-delivery/README.md +4 -2
- package/plugins/ai-delivery/dist/mcp-launcher.js +19 -8
- package/plugins/ai-delivery/mcp.json +10 -0
- package/plugins/ai-delivery/plugin.json +10 -0
- package/plugins/ai-delivery/runtime/dist/THIRD-PARTY-NOTICES.md +1010 -0
- package/plugins/ai-delivery/runtime/dist/cli.js +276 -0
- package/plugins/ai-delivery/runtime/package.json +13 -0
- package/plugins/ai-delivery/skills/intake-create/SKILL.md +1 -1
- package/plugins/ai-delivery/skills/pr-handoff/SKILL.md +14 -21
- package/plugins/ai-delivery/skills/worktree-lifecycle/SKILL.md +12 -23
- package/dist/services/deliveryRecordService.d.ts +0 -47
- package/dist/services/deliveryRecordService.js +0 -199
- package/dist/services/deliveryRecordService.js.map +0 -1
|
@@ -34,7 +34,7 @@ The earlier default-JSON requirement remains in issue history, not in the active
|
|
|
34
34
|
1. Use `issue_create` to create one coherent tracking issue with the applicable native issue metadata and relationships.
|
|
35
35
|
2. Use `issue_info` to inspect a known issue and `issue_update` for authoritative metadata, relationship, or lifecycle changes.
|
|
36
36
|
3. Run `issue_ready_check` before development. Resolve any reported gaps in the issue before proceeding.
|
|
37
|
-
4. Continue with `
|
|
37
|
+
4. Continue with `issue_start` and an explicit repository when the issue is ready; prepare its worktree through the host.
|
|
38
38
|
|
|
39
39
|
## CLI fallback
|
|
40
40
|
|
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "ai-delivery:pr-handoff"
|
|
3
|
-
description: Publish a
|
|
3
|
+
description: Publish a GitHub-linked change, submit exact-head independent App review and complete guarded delivery.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Pull request handoff
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Run contributor checks through the repository's normal workflow. Keep the resulting commit unchanged through publication and independent review; a changed head requires fresh checks and review.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Call `issue_pr_create` with explicit `repo`, issue number, a non-empty body and `dryRun: true`. Inspect configured actor and rule evidence, then create a draft from the GitHub-linked branch. Hosts own commits and pushes. Resolve missing credentials or same-actor routes; unknown approval eligibility is not approval.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
2. Call `issue_pr_create` with `dryRun: true` and inspect its `reviewRoute`: selected author and reviewer actors, credential sources, effective reviewer Contents grant, repository access and rule visibility. A visible required-approval rule with a read-only reviewer App grant reports `insufficient-permission`; arrange an eligible independent reviewer or have the operator grant Contents write, accept the installation update and refresh its token before publication. Contents write grants code-write access. Resolve missing credentials or same-actor errors before publication. Unknown grants or rule visibility remain unknown; Contents write is not required merely to submit a review.
|
|
14
|
-
3. Publish as a draft with `issue_pr_create`, then inspect the actual PR author with `issue_pr_info` or GitHub readback. The selected author credential must make the push and PR; do not switch to an ambient connector.
|
|
15
|
-
4. Obtain independent review of the exact pull request head. Submit its artifact with `issue_pr_review` and the configured reviewer `identity`, so the selected reviewer GitHub App makes the review. Inspect the returned `reviewState`, including `submittedReviewAuthorCanPushToRepository` when available, and the live `reviewDecision`.
|
|
16
|
-
5. Promote the unchanged PR with `issue_pr_create` (`draft: false`), inspect live required-review state and checks, then use `issue_finish` only when GitHub requirements are satisfied.
|
|
12
|
+
Obtain a read-only independent review of the exact remote commit, tree and complete diff. Submit its artifact with `issue_pr_review` using the configured reviewer App. A matching review is reused. Inspect GitHub's live required-review decision and checks; submission alone does not prove the approval counted. Resolve stale/dismissed reviews, blockers, failed checks and moved heads or bases without relaxing protection.
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
Promote the unchanged PR using `issue_pr_create` with `draft: false`. Finish only with satisfied GitHub requirements and fresh CLEAN eligibility. The merge mutation uses the independently reviewed SHA; finish confirms the intended PR merged before closing its issue. Hosts retain responsibility for local worktree cleanup.
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
ai-delivery --
|
|
25
|
-
ai-delivery --
|
|
26
|
-
|
|
27
|
-
ai-delivery --
|
|
28
|
-
ai-delivery --identity <configured-author> pr:create --issue <number> --ready
|
|
29
|
-
ai-delivery --identity <configured-author> pr:checks --pr <number>
|
|
30
|
-
ai-delivery --identity <configured-author> finish --issue <number> --pr <number>
|
|
16
|
+
```sh
|
|
17
|
+
ai-delivery --repo <owner/name> pr:create --issue <number> --body-file ./pr-body.md --dry-run
|
|
18
|
+
ai-delivery --repo <owner/name> pr:create --issue <number> --body-file ./pr-body.md
|
|
19
|
+
# Obtain independent exact-head review.
|
|
20
|
+
ai-delivery --repo <owner/name> pr:review --issue <number> --pr <number> --artifact ./review-artifact.json
|
|
21
|
+
ai-delivery --repo <owner/name> pr:create --issue <number> --ready
|
|
22
|
+
ai-delivery --repo <owner/name> pr:checks --pr <number>
|
|
23
|
+
ai-delivery --repo <owner/name> finish --issue <number> --pr <number> --reviewed-head <reviewed-sha>
|
|
31
24
|
```
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
CLI `--artifact` is a UTF-8 JSON file path. MCP takes the JSON content. Never fabricate effective model metadata or historical policy/evidence receipts. The artifact and counted independent App approval must bind the exact delivered head.
|
|
@@ -1,33 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "ai-delivery:worktree-lifecycle"
|
|
3
|
-
description:
|
|
3
|
+
description: Start a GitHub-linked issue branch, prepare a host-owned worktree and verify its change through repository contributor checks.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Host-owned worktree lifecycle
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Read user configuration and inspect `ai-delivery --repo <owner/name> config:resolve`. Confirm configured author and independent reviewer actors and repository access. Unknown GitHub rule visibility remains unknown.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Use `issue_info` and `issue_ready_check` with an explicit `repo`, then `issue_start` with the existing issue number to create or reuse its GitHub-linked branch. Prepare the local worktree using the host's supported worktree tools. Run the repository's own contributor checks, commit and push through its normal workflow. The ai-delivery runtime never executes repository policy modules or checks, or creates local worktrees. Continue to pull request handoff at the unchanged remote head.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
4. Run `issue_verify` after the commit. Continue to pull request handoff with the exact verified commit.
|
|
18
|
-
|
|
19
|
-
To park execution without removing the worktree, call `issue_update` with `park: true` or `ai-delivery update --issue <number> --park`. The Project shows Todo or Blocked from current native blockers; closed/Done remains Done. Resume through `issue_develop`/`develop` with the existing readiness checks. A retained worktree does not establish active execution.
|
|
20
|
-
|
|
21
|
-
For an unwitnessed legacy issue row, use the read-only `issue_worktree_transition_inspect` with purpose `active-resume` or `merged-cleanup`. Installation does not adopt the row. Preserve unknown historical evidence as original bytes; never treat it as current verification/review or operational closure. The supported closure family is the retained official public 0.3.5 archive/installed runtime admission, producer-bound run@3 and writers@1 on supported POSIX hosts. Missing closure, operative issue-cli v1/v2 or unknown resources must remain refused.
|
|
12
|
+
```sh
|
|
13
|
+
ai-delivery --repo <owner/name> ready:check --issue <number>
|
|
14
|
+
ai-delivery --repo <owner/name> start --issue <number>
|
|
15
|
+
# Prepare a host-owned worktree, implement, run contributor checks, commit and push.
|
|
16
|
+
```
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
Parking an issue with `issue_update({repo, issueNumber, park: true})` retains its remote tracking presentation. Worktree cleanup remains with the host owner.
|
|
24
19
|
|
|
25
|
-
|
|
20
|
+
Legacy `issue_worktree_transition_inspect` and `issue_worktree_transition_apply` preserve their separate custody contract. Preserve original bytes and accounting; unsupported configuration or closure bindings fail closed. Apply only an exact independently accepted plan with native personal-operator relinquishment, distinct reviewer-App acceptance, complete immutable inventory, runtime admission and quiescent writer proof. This skill grants no private adoption, hold release, launcher change, shared admission or protocol retirement authority.
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
ai-delivery --identity <configured-author> config:resolve
|
|
29
|
-
ai-delivery ready:check --issue <number>
|
|
30
|
-
ai-delivery develop --issue <number>
|
|
31
|
-
# edit, run focused checks, and commit in the prepared worktree
|
|
32
|
-
ai-delivery verify
|
|
33
|
-
```
|
|
22
|
+
This runtime's CLI/MCP cannot reconstruct the historical repository-policy binding, so those transition commands refuse. Use the original controller for their successful execution; retained engine tests do not imply compatibility of the new public entrypoint.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import * as z from 'zod/v4';
|
|
2
|
-
declare const DeliveryRecordSchema: z.ZodObject<{
|
|
3
|
-
blockerTimeMs: z.ZodNullable<z.ZodNumber>;
|
|
4
|
-
cycleTimeMs: z.ZodNumber;
|
|
5
|
-
firstPassApproved: z.ZodNullable<z.ZodBoolean>;
|
|
6
|
-
issueNumber: z.ZodNumber;
|
|
7
|
-
mergedAt: z.ZodISODateTime;
|
|
8
|
-
mergeSha: z.ZodString;
|
|
9
|
-
points: z.ZodNumber;
|
|
10
|
-
recordedAt: z.ZodISODateTime;
|
|
11
|
-
repository: z.ZodString;
|
|
12
|
-
reviewRounds: z.ZodNullable<z.ZodNumber>;
|
|
13
|
-
schemaVersion: z.ZodLiteral<"ai-delivery.delivery-record@1">;
|
|
14
|
-
terminalCleanupAt: z.ZodISODateTime;
|
|
15
|
-
}, z.core.$strict>;
|
|
16
|
-
export type DeliveryRecord = z.infer<typeof DeliveryRecordSchema>;
|
|
17
|
-
export interface PointBucketStatistics {
|
|
18
|
-
blockerMeasurementCount: number;
|
|
19
|
-
deliveries: number;
|
|
20
|
-
firstPassRate: null | number;
|
|
21
|
-
meanReviewRounds: null | number;
|
|
22
|
-
medianBlockerTimeMs: null | number;
|
|
23
|
-
medianCycleTimeMs: null | number;
|
|
24
|
-
points: DeliveryRecord['points'];
|
|
25
|
-
}
|
|
26
|
-
export interface VelocityReport {
|
|
27
|
-
planningCapacityPoints: number;
|
|
28
|
-
pointBuckets: PointBucketStatistics[];
|
|
29
|
-
rollingFourWeekMedianPoints: number;
|
|
30
|
-
schemaVersion: 'ai-delivery.velocity-report@1';
|
|
31
|
-
weeks: {
|
|
32
|
-
end: string;
|
|
33
|
-
mergedPoints: number;
|
|
34
|
-
start: string;
|
|
35
|
-
}[];
|
|
36
|
-
}
|
|
37
|
-
export declare function buildVelocityReport(records: readonly DeliveryRecord[], now?: Date, configuredPoints?: readonly number[]): VelocityReport;
|
|
38
|
-
export declare function getDeliveryRecords(projectRoot?: string): DeliveryRecord[];
|
|
39
|
-
export declare function recordMergedDeliveries(candidates: readonly DeliveryRecord[], projectRoot?: string): Promise<{
|
|
40
|
-
records: DeliveryRecord[];
|
|
41
|
-
state: 'already-recorded' | 'recorded';
|
|
42
|
-
}>;
|
|
43
|
-
export declare function recordMergedDelivery(candidate: DeliveryRecord, projectRoot?: string): Promise<{
|
|
44
|
-
record: DeliveryRecord;
|
|
45
|
-
state: 'already-recorded' | 'recorded';
|
|
46
|
-
}>;
|
|
47
|
-
export {};
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import * as z from 'zod/v4';
|
|
4
|
-
import { gitCommonDir } from '../git.js';
|
|
5
|
-
import { ensurePrivateDirectoryDurably, writePrivateJsonFileAtomically } from '../utils/atomicJson.js';
|
|
6
|
-
import { DeliveryError } from '../errors.js';
|
|
7
|
-
import { withLock } from '../utils/lockfile.js';
|
|
8
|
-
const deliveryRecordsPath = (root) => join(gitCommonDir(root), 'ai-delivery', 'deliveries.json');
|
|
9
|
-
const MS_PER_WEEK = 7 * 24 * 60 * 60 * 1000;
|
|
10
|
-
const DeliveryRecordSchema = z
|
|
11
|
-
.object({
|
|
12
|
-
blockerTimeMs: z.number().int().nonnegative().nullable(),
|
|
13
|
-
cycleTimeMs: z.number().int().nonnegative(),
|
|
14
|
-
firstPassApproved: z.boolean().nullable(),
|
|
15
|
-
issueNumber: z.number().int().positive(),
|
|
16
|
-
mergedAt: z.iso.datetime(),
|
|
17
|
-
mergeSha: z.string().regex(/^[0-9a-f]{40}$/u),
|
|
18
|
-
points: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
19
|
-
recordedAt: z.iso.datetime(),
|
|
20
|
-
repository: z.string().regex(/^[^/\s]+\/[^/\s]+$/u),
|
|
21
|
-
reviewRounds: z.number().int().positive().nullable(),
|
|
22
|
-
schemaVersion: z.literal('ai-delivery.delivery-record@1'),
|
|
23
|
-
terminalCleanupAt: z.iso.datetime(),
|
|
24
|
-
})
|
|
25
|
-
.strict()
|
|
26
|
-
.superRefine((record, context) => {
|
|
27
|
-
if (Date.parse(record.terminalCleanupAt) < Date.parse(record.mergedAt)) {
|
|
28
|
-
context.addIssue({
|
|
29
|
-
code: 'custom',
|
|
30
|
-
message: 'Terminal cleanup cannot precede the merge.',
|
|
31
|
-
path: ['terminalCleanupAt'],
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
if (Date.parse(record.recordedAt) < Date.parse(record.terminalCleanupAt)) {
|
|
35
|
-
context.addIssue({
|
|
36
|
-
code: 'custom',
|
|
37
|
-
message: 'Delivery recording cannot precede terminal cleanup.',
|
|
38
|
-
path: ['recordedAt'],
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
const DeliveryRecordFileSchema = z
|
|
43
|
-
.object({
|
|
44
|
-
records: z.array(DeliveryRecordSchema),
|
|
45
|
-
schemaVersion: z.literal('ai-delivery.delivery-records@1'),
|
|
46
|
-
})
|
|
47
|
-
.strict();
|
|
48
|
-
export function buildVelocityReport(records, now = new Date(), configuredPoints = []) {
|
|
49
|
-
if (!Number.isFinite(now.getTime())) {
|
|
50
|
-
throw new DeliveryError('Velocity report requires a valid observation time.');
|
|
51
|
-
}
|
|
52
|
-
const endMs = now.getTime();
|
|
53
|
-
const startMs = endMs - 4 * MS_PER_WEEK;
|
|
54
|
-
const selected = records.filter((record) => {
|
|
55
|
-
const mergedMs = Date.parse(record.mergedAt);
|
|
56
|
-
return mergedMs >= startMs && mergedMs < endMs;
|
|
57
|
-
});
|
|
58
|
-
const weeks = Array.from({ length: 4 }, (_, index) => {
|
|
59
|
-
const weekStart = startMs + index * MS_PER_WEEK;
|
|
60
|
-
const weekEnd = weekStart + MS_PER_WEEK;
|
|
61
|
-
return {
|
|
62
|
-
end: new Date(weekEnd).toISOString(),
|
|
63
|
-
mergedPoints: selected
|
|
64
|
-
.filter((record) => {
|
|
65
|
-
const mergedMs = Date.parse(record.mergedAt);
|
|
66
|
-
return mergedMs >= weekStart && mergedMs < weekEnd;
|
|
67
|
-
})
|
|
68
|
-
.reduce((sum, record) => sum + record.points, 0),
|
|
69
|
-
start: new Date(weekStart).toISOString(),
|
|
70
|
-
};
|
|
71
|
-
});
|
|
72
|
-
const rollingFourWeekMedianPoints = median(weeks.map((week) => week.mergedPoints)) ?? 0;
|
|
73
|
-
return {
|
|
74
|
-
planningCapacityPoints: Math.floor(rollingFourWeekMedianPoints * 0.8),
|
|
75
|
-
pointBuckets: [...new Set([...configuredPoints, ...selected.map((record) => record.points)])]
|
|
76
|
-
.sort((left, right) => left - right)
|
|
77
|
-
.map((points) => pointBucket(points, selected)),
|
|
78
|
-
rollingFourWeekMedianPoints,
|
|
79
|
-
schemaVersion: 'ai-delivery.velocity-report@1',
|
|
80
|
-
weeks,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
export function getDeliveryRecords(projectRoot = process.cwd()) {
|
|
84
|
-
const path = deliveryRecordsPath(projectRoot);
|
|
85
|
-
if (!existsSync(path)) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
return DeliveryRecordFileSchema.parse(JSON.parse(readFileSync(path, 'utf8'))).records;
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
throw new DeliveryError(`Delivery record store is invalid: ${error instanceof Error ? error.message : String(error)}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
export async function recordMergedDeliveries(candidates, projectRoot = process.cwd()) {
|
|
96
|
-
if (candidates.length === 0) {
|
|
97
|
-
throw new DeliveryError('Delivery recording requires at least one merged delivery.');
|
|
98
|
-
}
|
|
99
|
-
const candidateRecords = candidates.map((candidate) => DeliveryRecordSchema.parse(candidate));
|
|
100
|
-
ensurePrivateDirectoryDurably(join(gitCommonDir(projectRoot), 'ai-delivery'));
|
|
101
|
-
return await withLock(join(gitCommonDir(projectRoot), 'ai-delivery'), {
|
|
102
|
-
operation: () => {
|
|
103
|
-
const records = getDeliveryRecords(projectRoot);
|
|
104
|
-
const pending = [];
|
|
105
|
-
for (const candidate of candidateRecords) {
|
|
106
|
-
const existing = [...records, ...pending].find((value) => sameDeliveryIdentity(value, candidate));
|
|
107
|
-
if (existing !== undefined && !sameImmutableFacts(existing, candidate)) {
|
|
108
|
-
throw new DeliveryError('Delivery facts conflict with the existing immutable delivery record.');
|
|
109
|
-
}
|
|
110
|
-
if (existing === undefined) {
|
|
111
|
-
pending.push(candidate);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (pending.length > 0) {
|
|
115
|
-
writePrivateJsonFileAtomically(deliveryRecordsPath(projectRoot), {
|
|
116
|
-
records: [...records, ...pending].sort(compareDeliveryRecords),
|
|
117
|
-
schemaVersion: 'ai-delivery.delivery-records@1',
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
const readback = getDeliveryRecords(projectRoot);
|
|
121
|
-
const persisted = candidateRecords.map((candidate) => {
|
|
122
|
-
const match = readback.find((value) => sameDeliveryIdentity(value, candidate));
|
|
123
|
-
if (match === undefined || !sameImmutableFacts(match, candidate)) {
|
|
124
|
-
throw new DeliveryError('Delivery record readback did not match the merged delivery.');
|
|
125
|
-
}
|
|
126
|
-
return match;
|
|
127
|
-
});
|
|
128
|
-
return {
|
|
129
|
-
records: persisted,
|
|
130
|
-
state: pending.length === 0 ? 'already-recorded' : 'recorded',
|
|
131
|
-
};
|
|
132
|
-
},
|
|
133
|
-
projectRoot,
|
|
134
|
-
timeout: 5000,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
export async function recordMergedDelivery(candidate, projectRoot = process.cwd()) {
|
|
138
|
-
const result = await recordMergedDeliveries([candidate], projectRoot);
|
|
139
|
-
const [record] = result.records;
|
|
140
|
-
if (record === undefined) {
|
|
141
|
-
throw new DeliveryError('Delivery record batch did not return the merged delivery.');
|
|
142
|
-
}
|
|
143
|
-
return { record, state: result.state };
|
|
144
|
-
}
|
|
145
|
-
function compareDeliveryRecords(left, right) {
|
|
146
|
-
return (left.repository.localeCompare(right.repository) ||
|
|
147
|
-
left.issueNumber - right.issueNumber ||
|
|
148
|
-
left.mergeSha.localeCompare(right.mergeSha));
|
|
149
|
-
}
|
|
150
|
-
function median(values) {
|
|
151
|
-
if (values.length === 0) {
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
const sorted = [...values].sort((left, right) => left - right);
|
|
155
|
-
const middle = Math.floor(sorted.length / 2);
|
|
156
|
-
const upper = sorted[middle];
|
|
157
|
-
if (upper === undefined) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
if (sorted.length % 2 === 1) {
|
|
161
|
-
return upper;
|
|
162
|
-
}
|
|
163
|
-
const lower = sorted[middle - 1];
|
|
164
|
-
return lower === undefined ? upper : (lower + upper) / 2;
|
|
165
|
-
}
|
|
166
|
-
function pointBucket(points, records) {
|
|
167
|
-
const matches = records.filter((record) => record.points === points);
|
|
168
|
-
const blockerMeasurements = matches.flatMap((record) => record.blockerTimeMs === null ? [] : [record.blockerTimeMs]);
|
|
169
|
-
const firstPassMeasurements = matches.filter((record) => record.firstPassApproved !== null);
|
|
170
|
-
const reviewMeasurements = matches.flatMap((record) => (record.reviewRounds === null ? [] : [record.reviewRounds]));
|
|
171
|
-
return {
|
|
172
|
-
blockerMeasurementCount: blockerMeasurements.length,
|
|
173
|
-
deliveries: matches.length,
|
|
174
|
-
firstPassRate: firstPassMeasurements.length === 0
|
|
175
|
-
? null
|
|
176
|
-
: firstPassMeasurements.filter((record) => record.firstPassApproved).length / firstPassMeasurements.length,
|
|
177
|
-
meanReviewRounds: reviewMeasurements.length === 0
|
|
178
|
-
? null
|
|
179
|
-
: reviewMeasurements.reduce((sum, rounds) => sum + rounds, 0) / reviewMeasurements.length,
|
|
180
|
-
medianBlockerTimeMs: median(blockerMeasurements),
|
|
181
|
-
medianCycleTimeMs: median(matches.map((record) => record.cycleTimeMs)),
|
|
182
|
-
points,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
function sameDeliveryIdentity(left, right) {
|
|
186
|
-
return (left.repository === right.repository && left.issueNumber === right.issueNumber && left.mergeSha === right.mergeSha);
|
|
187
|
-
}
|
|
188
|
-
function sameImmutableFacts(left, right) {
|
|
189
|
-
return (left.blockerTimeMs === right.blockerTimeMs &&
|
|
190
|
-
left.cycleTimeMs === right.cycleTimeMs &&
|
|
191
|
-
left.firstPassApproved === right.firstPassApproved &&
|
|
192
|
-
left.issueNumber === right.issueNumber &&
|
|
193
|
-
left.mergeSha === right.mergeSha &&
|
|
194
|
-
left.mergedAt === right.mergedAt &&
|
|
195
|
-
left.points === right.points &&
|
|
196
|
-
left.repository === right.repository &&
|
|
197
|
-
left.reviewRounds === right.reviewRounds);
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=deliveryRecordService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deliveryRecordService.js","sourceRoot":"","sources":["../../src/services/deliveryRecordService.ts"],"names":[],"mappings":"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"}
|