openplanr 1.2.8 → 1.4.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.
- package/README.md +30 -3
- package/dist/agents/task-parser.d.ts.map +1 -1
- package/dist/agents/task-parser.js +8 -34
- package/dist/agents/task-parser.js.map +1 -1
- package/dist/ai/prompts/prompt-builder.d.ts +14 -0
- package/dist/ai/prompts/prompt-builder.d.ts.map +1 -1
- package/dist/ai/prompts/prompt-builder.js +32 -1
- package/dist/ai/prompts/prompt-builder.js.map +1 -1
- package/dist/ai/prompts/system-prompts.d.ts +3 -2
- package/dist/ai/prompts/system-prompts.d.ts.map +1 -1
- package/dist/ai/prompts/system-prompts.js +117 -7
- package/dist/ai/prompts/system-prompts.js.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.d.ts +62 -0
- package/dist/ai/schemas/ai-response-schemas.d.ts.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.js +51 -1
- package/dist/ai/schemas/ai-response-schemas.js.map +1 -1
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/ai/types.js +2 -0
- package/dist/ai/types.js.map +1 -1
- package/dist/cli/commands/backlog.d.ts +12 -0
- package/dist/cli/commands/backlog.d.ts.map +1 -1
- package/dist/cli/commands/backlog.js +88 -2
- package/dist/cli/commands/backlog.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +8 -2
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/linear.d.ts +8 -0
- package/dist/cli/commands/linear.d.ts.map +1 -0
- package/dist/cli/commands/linear.js +550 -0
- package/dist/cli/commands/linear.js.map +1 -0
- package/dist/cli/commands/quick.d.ts +17 -0
- package/dist/cli/commands/quick.d.ts.map +1 -1
- package/dist/cli/commands/quick.js +31 -15
- package/dist/cli/commands/quick.js.map +1 -1
- package/dist/cli/commands/revise.d.ts +9 -8
- package/dist/cli/commands/revise.d.ts.map +1 -1
- package/dist/cli/commands/revise.js +93 -25
- package/dist/cli/commands/revise.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +28 -0
- package/dist/cli/commands/spec.d.ts.map +1 -0
- package/dist/cli/commands/spec.js +529 -0
- package/dist/cli/commands/spec.js.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/models/schema.d.ts +44 -0
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +50 -0
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +188 -3
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/artifact-gathering.d.ts +4 -0
- package/dist/services/artifact-gathering.d.ts.map +1 -1
- package/dist/services/artifact-gathering.js +1 -1
- package/dist/services/artifact-gathering.js.map +1 -1
- package/dist/services/artifact-service.d.ts +12 -1
- package/dist/services/artifact-service.d.ts.map +1 -1
- package/dist/services/artifact-service.js +49 -6
- package/dist/services/artifact-service.js.map +1 -1
- package/dist/services/atomic-write-service.d.ts +2 -2
- package/dist/services/atomic-write-service.js +2 -2
- package/dist/services/audit-log-service.d.ts +3 -6
- package/dist/services/audit-log-service.d.ts.map +1 -1
- package/dist/services/audit-log-service.js +4 -7
- package/dist/services/audit-log-service.js.map +1 -1
- package/dist/services/cascade-service.d.ts +2 -2
- package/dist/services/cascade-service.js +3 -3
- package/dist/services/cascade-service.js.map +1 -1
- package/dist/services/config-service.d.ts.map +1 -1
- package/dist/services/config-service.js +1 -0
- package/dist/services/config-service.js.map +1 -1
- package/dist/services/credentials-service.js +2 -2
- package/dist/services/credentials-service.js.map +1 -1
- package/dist/services/diff-service.d.ts +1 -1
- package/dist/services/diff-service.js +1 -1
- package/dist/services/evidence-verifier.d.ts +1 -1
- package/dist/services/evidence-verifier.d.ts.map +1 -1
- package/dist/services/evidence-verifier.js +5 -2
- package/dist/services/evidence-verifier.js.map +1 -1
- package/dist/services/git-service.d.ts +4 -4
- package/dist/services/git-service.js +4 -4
- package/dist/services/graph-integrity.d.ts +2 -3
- package/dist/services/graph-integrity.d.ts.map +1 -1
- package/dist/services/graph-integrity.js +2 -3
- package/dist/services/graph-integrity.js.map +1 -1
- package/dist/services/linear/body-formatters.d.ts +69 -0
- package/dist/services/linear/body-formatters.d.ts.map +1 -0
- package/dist/services/linear/body-formatters.js +183 -0
- package/dist/services/linear/body-formatters.js.map +1 -0
- package/dist/services/linear/constants.d.ts +61 -0
- package/dist/services/linear/constants.d.ts.map +1 -0
- package/dist/services/linear/constants.js +84 -0
- package/dist/services/linear/constants.js.map +1 -0
- package/dist/services/linear/errors.d.ts +14 -0
- package/dist/services/linear/errors.d.ts.map +1 -0
- package/dist/services/linear/errors.js +106 -0
- package/dist/services/linear/errors.js.map +1 -0
- package/dist/services/linear/estimate-resolver.d.ts +50 -0
- package/dist/services/linear/estimate-resolver.d.ts.map +1 -0
- package/dist/services/linear/estimate-resolver.js +82 -0
- package/dist/services/linear/estimate-resolver.js.map +1 -0
- package/dist/services/linear/plan-builders.d.ts +64 -0
- package/dist/services/linear/plan-builders.d.ts.map +1 -0
- package/dist/services/linear/plan-builders.js +237 -0
- package/dist/services/linear/plan-builders.js.map +1 -0
- package/dist/services/linear/scope-loaders.d.ts +79 -0
- package/dist/services/linear/scope-loaders.d.ts.map +1 -0
- package/dist/services/linear/scope-loaders.js +227 -0
- package/dist/services/linear/scope-loaders.js.map +1 -0
- package/dist/services/linear/strategy-context.d.ts +66 -0
- package/dist/services/linear/strategy-context.d.ts.map +1 -0
- package/dist/services/linear/strategy-context.js +121 -0
- package/dist/services/linear/strategy-context.js.map +1 -0
- package/dist/services/linear-mapping-service.d.ts +11 -0
- package/dist/services/linear-mapping-service.d.ts.map +1 -0
- package/dist/services/linear-mapping-service.js +220 -0
- package/dist/services/linear-mapping-service.js.map +1 -0
- package/dist/services/linear-pull-service.d.ts +137 -0
- package/dist/services/linear-pull-service.d.ts.map +1 -0
- package/dist/services/linear-pull-service.js +720 -0
- package/dist/services/linear-pull-service.js.map +1 -0
- package/dist/services/linear-push-service.d.ts +86 -0
- package/dist/services/linear-push-service.d.ts.map +1 -0
- package/dist/services/linear-push-service.js +956 -0
- package/dist/services/linear-push-service.js.map +1 -0
- package/dist/services/linear-service.d.ts +122 -0
- package/dist/services/linear-service.d.ts.map +1 -0
- package/dist/services/linear-service.js +361 -0
- package/dist/services/linear-service.js.map +1 -0
- package/dist/services/prompt-service.d.ts +19 -0
- package/dist/services/prompt-service.d.ts.map +1 -1
- package/dist/services/prompt-service.js +64 -0
- package/dist/services/prompt-service.js.map +1 -1
- package/dist/services/revise-apply-service.d.ts +55 -0
- package/dist/services/revise-apply-service.d.ts.map +1 -0
- package/dist/services/revise-apply-service.js +255 -0
- package/dist/services/revise-apply-service.js.map +1 -0
- package/dist/services/revise-cache-service.d.ts +1 -1
- package/dist/services/revise-cache-service.js +1 -1
- package/dist/services/revise-plan-service.d.ts +38 -0
- package/dist/services/revise-plan-service.d.ts.map +1 -0
- package/dist/services/revise-plan-service.js +151 -0
- package/dist/services/revise-plan-service.js.map +1 -0
- package/dist/services/revise-service.d.ts +18 -11
- package/dist/services/revise-service.d.ts.map +1 -1
- package/dist/services/revise-service.js +57 -12
- package/dist/services/revise-service.js.map +1 -1
- package/dist/services/spec-service.d.ts +292 -0
- package/dist/services/spec-service.d.ts.map +1 -0
- package/dist/services/spec-service.js +805 -0
- package/dist/services/spec-service.js.map +1 -0
- package/dist/services/template-sections.d.ts +1 -1
- package/dist/services/template-sections.js +1 -1
- package/dist/templates/backlog/backlog-item.md.hbs +3 -0
- package/dist/templates/quick/quick-task.md.hbs +6 -0
- package/dist/templates/spec/spec-shaped.md.hbs +89 -0
- package/dist/templates/spec/spec.md.hbs +68 -0
- package/dist/templates/spec/story.md.hbs +51 -0
- package/dist/templates/spec/task.md.hbs +98 -0
- package/dist/utils/constants.d.ts +18 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +25 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/diff.d.ts +22 -1
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +136 -1
- package/dist/utils/diff.js.map +1 -1
- package/dist/utils/markdown.d.ts +23 -0
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js +79 -0
- package/dist/utils/markdown.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scale-aware snapping from OpenPlanr `storyPoints` → Linear `estimate` field.
|
|
3
|
+
*
|
|
4
|
+
* Linear's estimate field is numeric and must match the team's configured
|
|
5
|
+
* scale (`fibonacci`, `linear`, `exponential`, or `tShirt`). A value that
|
|
6
|
+
* isn't on the scale is rejected by the API, so we snap to the nearest
|
|
7
|
+
* allowed value before sending. Callers use the returned snap event to emit
|
|
8
|
+
* a debug log once per transformation.
|
|
9
|
+
*
|
|
10
|
+
* Scales mirror Linear's own SDK values — see `LinearIssueEstimationType`
|
|
11
|
+
* in `src/models/types.ts`.
|
|
12
|
+
*/
|
|
13
|
+
const FIBONACCI_SCALE = [0, 1, 2, 3, 5, 8, 13, 21];
|
|
14
|
+
const LINEAR_SCALE = [0, 1, 2, 3, 4, 5];
|
|
15
|
+
const EXPONENTIAL_SCALE = [0, 1, 2, 4, 8, 16];
|
|
16
|
+
function snapToNearest(value, scale) {
|
|
17
|
+
let best = scale[0];
|
|
18
|
+
let bestDistance = Math.abs(value - best);
|
|
19
|
+
for (const candidate of scale) {
|
|
20
|
+
const distance = Math.abs(value - candidate);
|
|
21
|
+
// Break ties toward the larger value — under-estimating is a common
|
|
22
|
+
// planning bias; snapping up ("4 is really a 5") leans against it.
|
|
23
|
+
if (distance < bestDistance || (distance === bestDistance && candidate > best)) {
|
|
24
|
+
best = candidate;
|
|
25
|
+
bestDistance = distance;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return best;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a local `storyPoints` (or `estimatedPoints`) value to a Linear
|
|
32
|
+
* `estimate` value given the team's scale.
|
|
33
|
+
*
|
|
34
|
+
* Precedence for the raw local value:
|
|
35
|
+
* 1. `frontmatter.estimatedPoints` — canonical name written by
|
|
36
|
+
* `planr estimate --save` (see `src/cli/commands/estimate.ts`).
|
|
37
|
+
* 2. `frontmatter.storyPoints` — alias accepted for hand-edited files or
|
|
38
|
+
* direct AI-response copies that used the schema field name verbatim.
|
|
39
|
+
*
|
|
40
|
+
* Returns one of:
|
|
41
|
+
* - `mapped` — include `estimate: <value>` in the push input
|
|
42
|
+
* - `skip-*` — omit the `estimate` field; `kind` carries the reason for
|
|
43
|
+
* logging / dry-run display
|
|
44
|
+
*/
|
|
45
|
+
export function resolveEstimateForPush(frontmatter, scale) {
|
|
46
|
+
if (scale === 'notUsed' || !scale) {
|
|
47
|
+
return { kind: 'skip-not-used' };
|
|
48
|
+
}
|
|
49
|
+
if (scale === 'tShirt') {
|
|
50
|
+
// No safe numeric → XS/S/M/L/XL mapping without user config. Skip.
|
|
51
|
+
return { kind: 'skip-t-shirt' };
|
|
52
|
+
}
|
|
53
|
+
const rawLocal = frontmatter.estimatedPoints !== undefined
|
|
54
|
+
? frontmatter.estimatedPoints
|
|
55
|
+
: frontmatter.storyPoints;
|
|
56
|
+
if (rawLocal === undefined || rawLocal === null || rawLocal === '') {
|
|
57
|
+
return { kind: 'skip-no-local-value' };
|
|
58
|
+
}
|
|
59
|
+
const parsed = typeof rawLocal === 'number' ? rawLocal : Number(rawLocal);
|
|
60
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
61
|
+
return { kind: 'skip-invalid-value', rawValue: rawLocal };
|
|
62
|
+
}
|
|
63
|
+
const allowed = scale === 'fibonacci'
|
|
64
|
+
? FIBONACCI_SCALE
|
|
65
|
+
: scale === 'linear'
|
|
66
|
+
? LINEAR_SCALE
|
|
67
|
+
: scale === 'exponential'
|
|
68
|
+
? EXPONENTIAL_SCALE
|
|
69
|
+
: undefined;
|
|
70
|
+
if (!allowed) {
|
|
71
|
+
// Unknown scale value returned by Linear — skip rather than guess.
|
|
72
|
+
return { kind: 'skip-not-used' };
|
|
73
|
+
}
|
|
74
|
+
const snapped = snapToNearest(parsed, allowed);
|
|
75
|
+
return {
|
|
76
|
+
kind: 'mapped',
|
|
77
|
+
estimate: snapped,
|
|
78
|
+
originalValue: parsed,
|
|
79
|
+
snapped: snapped !== parsed,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=estimate-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate-resolver.js","sourceRoot":"","sources":["../../../src/services/linear/estimate-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure plan-building for `planr linear push --dry-run`. Takes loaded scopes
|
|
3
|
+
* and returns `LinearPushPlan` objects with per-kind row counts. No Linear
|
|
4
|
+
* API calls; no mutations. Epic-scope plans cascade rows for linked QT/BL.
|
|
5
|
+
*/
|
|
6
|
+
import type { Epic, Feature, OpenPlanrConfig, UserStory } from '../../models/types.js';
|
|
7
|
+
import { type ScopedFeature, type ScopedTaskFile } from './scope-loaders.js';
|
|
8
|
+
export type LinearPushItemKind = 'project' | 'feature' | 'story' | 'taskList' | 'quickTask' | 'backlogItem';
|
|
9
|
+
export type LinearPushAction = 'create' | 'update' | 'skip';
|
|
10
|
+
/** Scope of a granular push — what subtree `runLinearPush(artifactId)` touches. */
|
|
11
|
+
export type LinearPushScope = 'epic' | 'feature' | 'story' | 'taskFile' | 'quick' | 'backlog';
|
|
12
|
+
export interface LinearPushPlanRow {
|
|
13
|
+
kind: LinearPushItemKind;
|
|
14
|
+
/** Epic id, feature id, story id, or task-file id for this row. */
|
|
15
|
+
artifactId: string;
|
|
16
|
+
title: string;
|
|
17
|
+
action: LinearPushAction;
|
|
18
|
+
detail?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface LinearPushPlan {
|
|
21
|
+
/** The artifact the user pointed `planr linear push` at (any supported prefix). */
|
|
22
|
+
rootArtifactId: string;
|
|
23
|
+
/** The epic that owns this push's subtree; `undefined` for standalone QT/BL pushes. */
|
|
24
|
+
epicId?: string;
|
|
25
|
+
scope: LinearPushScope;
|
|
26
|
+
rows: LinearPushPlanRow[];
|
|
27
|
+
/** Counts by kind for non-`skip` rows. Missing kinds are 0. */
|
|
28
|
+
counts: {
|
|
29
|
+
project: number;
|
|
30
|
+
features: number;
|
|
31
|
+
stories: number;
|
|
32
|
+
taskLists: number;
|
|
33
|
+
quickTasks: number;
|
|
34
|
+
backlogItems: number;
|
|
35
|
+
total: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract the linked epic id from QT / BL frontmatter. Canonical field is
|
|
40
|
+
* `epicId`; `parentEpic` is accepted as a compat alias for hand-authored
|
|
41
|
+
* files. Empty strings are normalised to `undefined`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getLinkedEpicId(fm: Record<string, unknown>): string | undefined;
|
|
44
|
+
export declare function projectRow(epic: Epic): LinearPushPlanRow;
|
|
45
|
+
export declare function featureRow(f: Feature): LinearPushPlanRow;
|
|
46
|
+
export declare function storyRow(s: UserStory): LinearPushPlanRow;
|
|
47
|
+
export declare function taskListPlanRow(featureId: string, taskFiles: ScopedTaskFile[], hasBody: boolean, hadIssue: boolean): LinearPushPlanRow;
|
|
48
|
+
export declare function applyUpdateOnly(rows: LinearPushPlanRow[], updateOnly: boolean): LinearPushPlanRow[];
|
|
49
|
+
export declare function summarizePlan(rootArtifactId: string, epicId: string | undefined, scope: LinearPushScope, rows: LinearPushPlanRow[]): LinearPushPlan;
|
|
50
|
+
export declare function buildFeaturePlanRows(projectDir: string, config: OpenPlanrConfig, sf: ScopedFeature): Promise<LinearPushPlanRow[]>;
|
|
51
|
+
export declare function buildEpicPlanRows(projectDir: string, config: OpenPlanrConfig, epicScope: {
|
|
52
|
+
epic: Epic;
|
|
53
|
+
features: ScopedFeature[];
|
|
54
|
+
}): Promise<LinearPushPlanRow[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Build a push preview (and counts) for `planr linear push --dry-run` at any
|
|
57
|
+
* granularity. Accepts any supported artifact id prefix (EPIC/FEAT/US/TASK/
|
|
58
|
+
* QT/BL); returns `null` when the artifact can't be resolved or is not
|
|
59
|
+
* pushable (ADR/SPRINT/checklist).
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildLinearPushPlan(projectDir: string, config: OpenPlanrConfig, artifactId: string, options?: {
|
|
62
|
+
updateOnly?: boolean;
|
|
63
|
+
}): Promise<LinearPushPlan | null>;
|
|
64
|
+
//# sourceMappingURL=plan-builders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-builders.d.ts","sourceRoot":"","sources":["../../../src/services/linear/plan-builders.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure plan-building for `planr linear push --dry-run`. Takes loaded scopes
|
|
3
|
+
* and returns `LinearPushPlan` objects with per-kind row counts. No Linear
|
|
4
|
+
* API calls; no mutations. Epic-scope plans cascade rows for linked QT/BL.
|
|
5
|
+
*/
|
|
6
|
+
import { findArtifactTypeById, listArtifacts, readArtifact } from '../artifact-service.js';
|
|
7
|
+
import { buildMergedTaskListBody, toOptionalString } from './body-formatters.js';
|
|
8
|
+
import { loadForBacklogItem, loadForFeature, loadForQuickTask, loadForStory, loadForTaskFile, loadLinearPushScope, } from './scope-loaders.js';
|
|
9
|
+
/**
|
|
10
|
+
* Extract the linked epic id from QT / BL frontmatter. Canonical field is
|
|
11
|
+
* `epicId`; `parentEpic` is accepted as a compat alias for hand-authored
|
|
12
|
+
* files. Empty strings are normalised to `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export function getLinkedEpicId(fm) {
|
|
15
|
+
return toOptionalString(fm.epicId) ?? toOptionalString(fm.parentEpic);
|
|
16
|
+
}
|
|
17
|
+
function sortByArtifactId(a, b) {
|
|
18
|
+
return a.id.localeCompare(b.id, undefined, { numeric: true });
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Per-kind row builders
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
export function projectRow(epic) {
|
|
24
|
+
const id = epic.linearProjectId;
|
|
25
|
+
return {
|
|
26
|
+
kind: 'project',
|
|
27
|
+
artifactId: epic.id,
|
|
28
|
+
title: epic.title.trim() || epic.id,
|
|
29
|
+
action: id ? 'update' : 'create',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function featureRow(f) {
|
|
33
|
+
return {
|
|
34
|
+
kind: 'feature',
|
|
35
|
+
artifactId: f.id,
|
|
36
|
+
title: f.title.trim() || f.id,
|
|
37
|
+
action: f.linearIssueId ? 'update' : 'create',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function storyRow(s) {
|
|
41
|
+
return {
|
|
42
|
+
kind: 'story',
|
|
43
|
+
artifactId: s.id,
|
|
44
|
+
title: s.title.trim() || s.id,
|
|
45
|
+
action: s.linearIssueId ? 'update' : 'create',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function taskListPlanRow(featureId, taskFiles, hasBody, hadIssue) {
|
|
49
|
+
if (!hasBody && !hadIssue) {
|
|
50
|
+
return {
|
|
51
|
+
kind: 'taskList',
|
|
52
|
+
artifactId: featureId,
|
|
53
|
+
title: `Tasks (${featureId})`,
|
|
54
|
+
action: 'skip',
|
|
55
|
+
detail: 'No task checkbox lines in task file(s) for this feature.',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const label = taskFiles[0]?.id ?? featureId;
|
|
59
|
+
return {
|
|
60
|
+
kind: 'taskList',
|
|
61
|
+
artifactId: label,
|
|
62
|
+
title: `Tasks: ${featureId}`,
|
|
63
|
+
action: hadIssue ? 'update' : 'create',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function applyUpdateOnly(rows, updateOnly) {
|
|
67
|
+
if (!updateOnly)
|
|
68
|
+
return rows;
|
|
69
|
+
return rows.map((r) => r.action === 'create'
|
|
70
|
+
? {
|
|
71
|
+
...r,
|
|
72
|
+
action: 'skip',
|
|
73
|
+
detail: r.detail
|
|
74
|
+
? `${r.detail} (not created: --update-only)`
|
|
75
|
+
: 'not created: --update-only',
|
|
76
|
+
}
|
|
77
|
+
: r);
|
|
78
|
+
}
|
|
79
|
+
export function summarizePlan(rootArtifactId, epicId, scope, rows) {
|
|
80
|
+
const countKind = (k) => rows.filter((r) => r.kind === k && r.action !== 'skip').length;
|
|
81
|
+
const project = countKind('project');
|
|
82
|
+
const features = countKind('feature');
|
|
83
|
+
const stories = countKind('story');
|
|
84
|
+
const taskLists = countKind('taskList');
|
|
85
|
+
const quickTasks = countKind('quickTask');
|
|
86
|
+
const backlogItems = countKind('backlogItem');
|
|
87
|
+
return {
|
|
88
|
+
rootArtifactId,
|
|
89
|
+
epicId,
|
|
90
|
+
scope,
|
|
91
|
+
rows,
|
|
92
|
+
counts: {
|
|
93
|
+
project,
|
|
94
|
+
features,
|
|
95
|
+
stories,
|
|
96
|
+
taskLists,
|
|
97
|
+
quickTasks,
|
|
98
|
+
backlogItems,
|
|
99
|
+
total: project + features + stories + taskLists + quickTasks + backlogItems,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Scope-level row assembly
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
export async function buildFeaturePlanRows(projectDir, config, sf) {
|
|
107
|
+
const rows = [];
|
|
108
|
+
rows.push(featureRow(sf.data));
|
|
109
|
+
for (const st of sf.stories) {
|
|
110
|
+
rows.push(storyRow(st.data));
|
|
111
|
+
}
|
|
112
|
+
const withLinear = await Promise.all(sf.taskFiles.map(async (tf) => {
|
|
113
|
+
const a = await readArtifact(projectDir, config, 'task', tf.id);
|
|
114
|
+
return { tf, issueId: toOptionalString(a?.data.linearIssueId) };
|
|
115
|
+
}));
|
|
116
|
+
const hadIssue = Boolean(withLinear.find((x) => x.issueId)?.issueId);
|
|
117
|
+
const body = await buildMergedTaskListBody(projectDir, config, sf.data.id, sf.taskFiles);
|
|
118
|
+
const hasBody = body.trim().length > 0;
|
|
119
|
+
rows.push(taskListPlanRow(sf.data.id, sf.taskFiles, hasBody, hadIssue));
|
|
120
|
+
return rows;
|
|
121
|
+
}
|
|
122
|
+
export async function buildEpicPlanRows(projectDir, config, epicScope) {
|
|
123
|
+
const rows = [];
|
|
124
|
+
rows.push(projectRow(epicScope.epic));
|
|
125
|
+
for (const sf of epicScope.features) {
|
|
126
|
+
rows.push(...(await buildFeaturePlanRows(projectDir, config, sf)));
|
|
127
|
+
}
|
|
128
|
+
// Linked QT / BL artifacts get their own rows so `--dry-run` matches what
|
|
129
|
+
// `runLinearPush` would actually touch.
|
|
130
|
+
const quicks = await listArtifacts(projectDir, config, 'quick');
|
|
131
|
+
for (const q of quicks.sort(sortByArtifactId)) {
|
|
132
|
+
const art = await readArtifact(projectDir, config, 'quick', q.id);
|
|
133
|
+
if (!art || getLinkedEpicId(art.data) !== epicScope.epic.id)
|
|
134
|
+
continue;
|
|
135
|
+
const hasId = Boolean(toOptionalString(art.data.linearIssueId));
|
|
136
|
+
rows.push({
|
|
137
|
+
kind: 'quickTask',
|
|
138
|
+
artifactId: q.id,
|
|
139
|
+
title: art.data.title?.trim() || q.title || q.id,
|
|
140
|
+
action: hasId ? 'update' : 'create',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const backlogs = await listArtifacts(projectDir, config, 'backlog');
|
|
144
|
+
for (const b of backlogs.sort(sortByArtifactId)) {
|
|
145
|
+
const art = await readArtifact(projectDir, config, 'backlog', b.id);
|
|
146
|
+
if (!art || getLinkedEpicId(art.data) !== epicScope.epic.id)
|
|
147
|
+
continue;
|
|
148
|
+
const hasId = Boolean(toOptionalString(art.data.linearIssueId));
|
|
149
|
+
rows.push({
|
|
150
|
+
kind: 'backlogItem',
|
|
151
|
+
artifactId: b.id,
|
|
152
|
+
title: art.data.title?.trim() || b.title || b.id,
|
|
153
|
+
action: hasId ? 'update' : 'create',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return rows;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Build a push preview (and counts) for `planr linear push --dry-run` at any
|
|
160
|
+
* granularity. Accepts any supported artifact id prefix (EPIC/FEAT/US/TASK/
|
|
161
|
+
* QT/BL); returns `null` when the artifact can't be resolved or is not
|
|
162
|
+
* pushable (ADR/SPRINT/checklist).
|
|
163
|
+
*/
|
|
164
|
+
export async function buildLinearPushPlan(projectDir, config, artifactId, options) {
|
|
165
|
+
const updateOnly = options?.updateOnly === true;
|
|
166
|
+
const type = findArtifactTypeById(artifactId);
|
|
167
|
+
if (!type)
|
|
168
|
+
return null;
|
|
169
|
+
if (type === 'epic') {
|
|
170
|
+
const scope = await loadLinearPushScope(projectDir, config, artifactId);
|
|
171
|
+
if (!scope)
|
|
172
|
+
return null;
|
|
173
|
+
const rows = applyUpdateOnly(await buildEpicPlanRows(projectDir, config, scope), updateOnly);
|
|
174
|
+
return summarizePlan(artifactId, scope.epic.id, 'epic', rows);
|
|
175
|
+
}
|
|
176
|
+
if (type === 'feature') {
|
|
177
|
+
const ctx = await loadForFeature(projectDir, config, artifactId);
|
|
178
|
+
if (!ctx)
|
|
179
|
+
return null;
|
|
180
|
+
const rows = applyUpdateOnly(await buildFeaturePlanRows(projectDir, config, ctx.sf), updateOnly);
|
|
181
|
+
return summarizePlan(artifactId, ctx.epic.id, 'feature', rows);
|
|
182
|
+
}
|
|
183
|
+
if (type === 'story') {
|
|
184
|
+
const ctx = await loadForStory(projectDir, config, artifactId);
|
|
185
|
+
if (!ctx)
|
|
186
|
+
return null;
|
|
187
|
+
const rows = applyUpdateOnly([storyRow(ctx.story.data)], updateOnly);
|
|
188
|
+
return summarizePlan(artifactId, ctx.epic.id, 'story', rows);
|
|
189
|
+
}
|
|
190
|
+
if (type === 'task') {
|
|
191
|
+
const ctx = await loadForTaskFile(projectDir, config, artifactId);
|
|
192
|
+
if (!ctx)
|
|
193
|
+
return null;
|
|
194
|
+
const withLinear = await Promise.all(ctx.sf.taskFiles.map(async (tf) => {
|
|
195
|
+
const a = await readArtifact(projectDir, config, 'task', tf.id);
|
|
196
|
+
return { tf, issueId: toOptionalString(a?.data.linearIssueId) };
|
|
197
|
+
}));
|
|
198
|
+
const hadIssue = Boolean(withLinear.find((x) => x.issueId)?.issueId);
|
|
199
|
+
const body = await buildMergedTaskListBody(projectDir, config, ctx.sf.data.id, ctx.sf.taskFiles);
|
|
200
|
+
const hasBody = body.trim().length > 0;
|
|
201
|
+
const rows = applyUpdateOnly([taskListPlanRow(ctx.sf.data.id, ctx.sf.taskFiles, hasBody, hadIssue)], updateOnly);
|
|
202
|
+
return summarizePlan(artifactId, ctx.epic.id, 'taskFile', rows);
|
|
203
|
+
}
|
|
204
|
+
if (type === 'quick') {
|
|
205
|
+
const qt = await loadForQuickTask(projectDir, config, artifactId);
|
|
206
|
+
if (!qt)
|
|
207
|
+
return null;
|
|
208
|
+
const hasId = Boolean(toOptionalString(qt.frontmatter.linearIssueId));
|
|
209
|
+
const rows = applyUpdateOnly([
|
|
210
|
+
{
|
|
211
|
+
kind: 'quickTask',
|
|
212
|
+
artifactId,
|
|
213
|
+
title: qt.title.trim() || qt.id,
|
|
214
|
+
action: hasId ? 'update' : 'create',
|
|
215
|
+
},
|
|
216
|
+
], updateOnly);
|
|
217
|
+
return summarizePlan(artifactId, undefined, 'quick', rows);
|
|
218
|
+
}
|
|
219
|
+
if (type === 'backlog') {
|
|
220
|
+
const bl = await loadForBacklogItem(projectDir, config, artifactId);
|
|
221
|
+
if (!bl)
|
|
222
|
+
return null;
|
|
223
|
+
const hasId = Boolean(toOptionalString(bl.frontmatter.linearIssueId));
|
|
224
|
+
const rows = applyUpdateOnly([
|
|
225
|
+
{
|
|
226
|
+
kind: 'backlogItem',
|
|
227
|
+
artifactId,
|
|
228
|
+
title: bl.title.trim() || bl.id,
|
|
229
|
+
action: hasId ? 'update' : 'create',
|
|
230
|
+
},
|
|
231
|
+
], updateOnly);
|
|
232
|
+
return summarizePlan(artifactId, undefined, 'backlog', rows);
|
|
233
|
+
}
|
|
234
|
+
// sprint / adr / checklist — not supported.
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=plan-builders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-builders.js","sourceRoot":"","sources":["../../../src/services/linear/plan-builders.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure data loaders that hydrate OpenPlanr artifacts into the shapes the
|
|
3
|
+
* Linear push expects. No Linear API calls, no mutations — just filesystem
|
|
4
|
+
* reads + frontmatter parsing. Every scope-level push function routes
|
|
5
|
+
* through one of these loaders first.
|
|
6
|
+
*/
|
|
7
|
+
import type { Epic, Feature, OpenPlanrConfig, UserStory } from '../../models/types.js';
|
|
8
|
+
export interface ScopedTaskFile {
|
|
9
|
+
id: string;
|
|
10
|
+
title: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ScopedStory {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
data: UserStory;
|
|
16
|
+
/** Raw YAML frontmatter — carries fields not mapped onto the typed `data`
|
|
17
|
+
* (e.g. `estimatedPoints`, `storyPoints` for Linear estimate sync). */
|
|
18
|
+
frontmatter: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface ScopedFeature {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
data: Feature;
|
|
24
|
+
/** Raw YAML frontmatter — same purpose as ScopedStory.frontmatter. */
|
|
25
|
+
frontmatter: Record<string, unknown>;
|
|
26
|
+
stories: ScopedStory[];
|
|
27
|
+
taskFiles: ScopedTaskFile[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Shape needed to push a standalone artifact (QT or BL) — the raw markdown
|
|
31
|
+
* (so QT can parse + re-render its checkbox list) plus the frontmatter
|
|
32
|
+
* record (linear* fields, epicId link, etc.).
|
|
33
|
+
*/
|
|
34
|
+
export interface ScopedStandaloneArtifact {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
raw: string;
|
|
38
|
+
frontmatter: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load the full epic subtree (epic frontmatter + features + stories per
|
|
42
|
+
* feature + task-file ids per feature). Filters by `epicId` on each child
|
|
43
|
+
* artifact.
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadLinearPushScope(projectDir: string, config: OpenPlanrConfig, epicId: string): Promise<{
|
|
46
|
+
epic: Epic;
|
|
47
|
+
features: ScopedFeature[];
|
|
48
|
+
} | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Parent-chain context needed to push a feature: the feature itself (with
|
|
51
|
+
* its stories and task files) plus its parent epic. Returns `null` if the
|
|
52
|
+
* feature can't be resolved or has no valid `epicId` pointer.
|
|
53
|
+
*/
|
|
54
|
+
export declare function loadForFeature(projectDir: string, config: OpenPlanrConfig, featureId: string): Promise<{
|
|
55
|
+
epic: Epic;
|
|
56
|
+
sf: ScopedFeature;
|
|
57
|
+
} | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Parent-chain context needed to push a story: the story itself, its
|
|
60
|
+
* feature (with sibling stories + tasklists) and the containing epic.
|
|
61
|
+
* Returns `null` if any link in the chain is missing.
|
|
62
|
+
*/
|
|
63
|
+
export declare function loadForStory(projectDir: string, config: OpenPlanrConfig, storyId: string): Promise<{
|
|
64
|
+
epic: Epic;
|
|
65
|
+
sf: ScopedFeature;
|
|
66
|
+
story: ScopedStory;
|
|
67
|
+
} | null>;
|
|
68
|
+
/**
|
|
69
|
+
* Parent-chain context needed to push a task file: the containing feature
|
|
70
|
+
* (with all its task files merged into one Linear sub-issue body) and the
|
|
71
|
+
* epic.
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadForTaskFile(projectDir: string, config: OpenPlanrConfig, taskId: string): Promise<{
|
|
74
|
+
epic: Epic;
|
|
75
|
+
sf: ScopedFeature;
|
|
76
|
+
} | null>;
|
|
77
|
+
export declare function loadForQuickTask(projectDir: string, config: OpenPlanrConfig, qtId: string): Promise<ScopedStandaloneArtifact | null>;
|
|
78
|
+
export declare function loadForBacklogItem(projectDir: string, config: OpenPlanrConfig, blId: string): Promise<ScopedStandaloneArtifact | null>;
|
|
79
|
+
//# sourceMappingURL=scope-loaders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-loaders.d.ts","sourceRoot":"","sources":["../../../src/services/linear/scope-loaders.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAc,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAkBnG,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB;2EACuE;IACvE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA8G3D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAAC,CAUnD;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IACT,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,aAAa,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;CACpB,GAAG,IAAI,CAAC,CAUR;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAAC,CAMnD;AAwBD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAW1C;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAW1C"}
|