@codyswann/lisa 2.293.1 → 2.294.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/dist/cli/deploy-status-adapter-github.d.ts +20 -0
- package/dist/cli/deploy-status-adapter-github.d.ts.map +1 -0
- package/dist/cli/deploy-status-adapter-github.js +167 -0
- package/dist/cli/deploy-status-adapter-github.js.map +1 -0
- package/dist/cli/deploy-status-adapter-jira.d.ts +18 -0
- package/dist/cli/deploy-status-adapter-jira.d.ts.map +1 -0
- package/dist/cli/deploy-status-adapter-jira.js +215 -0
- package/dist/cli/deploy-status-adapter-jira.js.map +1 -0
- package/dist/cli/deploy-status-adapter-linear.d.ts +16 -0
- package/dist/cli/deploy-status-adapter-linear.d.ts.map +1 -0
- package/dist/cli/deploy-status-adapter-linear.js +204 -0
- package/dist/cli/deploy-status-adapter-linear.js.map +1 -0
- package/dist/cli/deploy-status-adapter-shared.d.ts +57 -0
- package/dist/cli/deploy-status-adapter-shared.d.ts.map +1 -0
- package/dist/cli/deploy-status-adapter-shared.js +62 -0
- package/dist/cli/deploy-status-adapter-shared.js.map +1 -0
- package/dist/cli/deploy-status-adapter.d.ts +49 -0
- package/dist/cli/deploy-status-adapter.d.ts.map +1 -0
- package/dist/cli/deploy-status-adapter.js +87 -0
- package/dist/cli/deploy-status-adapter.js.map +1 -0
- package/dist/cli/deploy-status-refs.d.ts +70 -0
- package/dist/cli/deploy-status-refs.d.ts.map +1 -0
- package/dist/cli/deploy-status-refs.js +195 -0
- package/dist/cli/deploy-status-refs.js.map +1 -0
- package/dist/cli/deploy-status-sync-cmd.d.ts +23 -0
- package/dist/cli/deploy-status-sync-cmd.d.ts.map +1 -0
- package/dist/cli/deploy-status-sync-cmd.js +75 -0
- package/dist/cli/deploy-status-sync-cmd.js.map +1 -0
- package/dist/cli/deploy-status-sync-engine.d.ts +49 -0
- package/dist/cli/deploy-status-sync-engine.d.ts.map +1 -0
- package/dist/cli/deploy-status-sync-engine.js +214 -0
- package/dist/cli/deploy-status-sync-engine.js.map +1 -0
- package/dist/cli/deploy-status-sync-exec.d.ts +73 -0
- package/dist/cli/deploy-status-sync-exec.d.ts.map +1 -0
- package/dist/cli/deploy-status-sync-exec.js +95 -0
- package/dist/cli/deploy-status-sync-exec.js.map +1 -0
- package/dist/cli/gate-commands.d.ts +3 -1
- package/dist/cli/gate-commands.d.ts.map +1 -1
- package/dist/cli/gate-commands.js +26 -0
- package/dist/cli/gate-commands.js.map +1 -1
- package/dist/cli/index.d.ts +2 -7
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/kane-commands.d.ts +21 -0
- package/dist/cli/kane-commands.d.ts.map +1 -0
- package/dist/cli/kane-commands.js +44 -0
- package/dist/cli/kane-commands.js.map +1 -0
- package/dist/cli/update-check.d.ts +8 -0
- package/dist/cli/update-check.d.ts.map +1 -1
- package/dist/cli/update-check.js +4 -2
- package/dist/cli/update-check.js.map +1 -1
- package/dist/core/deploy-status-sync.d.ts +15 -0
- package/dist/core/deploy-status-sync.d.ts.map +1 -1
- package/dist/core/deploy-status-sync.js +57 -19
- package/dist/core/deploy-status-sync.js.map +1 -1
- package/dist/core/deploy-status-transition.d.ts +97 -0
- package/dist/core/deploy-status-transition.d.ts.map +1 -0
- package/dist/core/deploy-status-transition.js +134 -0
- package/dist/core/deploy-status-transition.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +23 -2
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/rules/eager/config-resolution.md +3 -2
- package/plugins/lisa/rules/reference/config-resolution.md +13 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/eager/config-resolution.md +3 -2
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +13 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +13 -1
- package/plugins/lisa-cursor/rules/config-resolution.mdc +3 -2
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/eager/config-resolution.md +3 -2
- package/plugins/src/base/rules/reference/config-resolution.md +13 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ExecGh, type TrackerAdapter } from "./deploy-status-adapter-shared.js";
|
|
2
|
+
/** Construction options for {@link createGithubAdapter}. */
|
|
3
|
+
export interface GithubAdapterOptions {
|
|
4
|
+
/** `owner/repo` the canonical refs belong to */
|
|
5
|
+
readonly repository: string;
|
|
6
|
+
/** Ladder done vocabulary, lowest rung first (config-sourced) */
|
|
7
|
+
readonly doneStatuses: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
/** Injectable collaborators for {@link createGithubAdapter}. */
|
|
10
|
+
export interface GithubAdapterDeps {
|
|
11
|
+
readonly execGh: ExecGh;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create the GitHub adapter.
|
|
15
|
+
* @param options - Repository and done vocabulary
|
|
16
|
+
* @param deps - gh executor
|
|
17
|
+
* @returns Tracker adapter over gh
|
|
18
|
+
*/
|
|
19
|
+
export declare function createGithubAdapter(options: GithubAdapterOptions, deps: GithubAdapterDeps): TrackerAdapter;
|
|
20
|
+
//# sourceMappingURL=deploy-status-adapter-github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-status-adapter-github.d.ts","sourceRoot":"","sources":["../../src/cli/deploy-status-adapter-github.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAC;AAE3C,4DAA4D;AAC5D,MAAM,WAAW,oBAAoB;IACnC,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAgLD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,iBAAiB,GACtB,cAAc,CAgBhB"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub tracker adapter for deploy-status-sync: label transitions, one
|
|
3
|
+
* marker-managed comment, and native closure — all via `gh` with fixed argv
|
|
4
|
+
* (ambient `gh` / `GITHUB_TOKEN` auth; credentials never in argv).
|
|
5
|
+
* @module cli/deploy-status-adapter-github
|
|
6
|
+
*/
|
|
7
|
+
import { DEPLOY_STATUS_SYNC_MARKER, } from "../core/deploy-status-transition.js";
|
|
8
|
+
import { deriveLabelState, } from "./deploy-status-adapter-shared.js";
|
|
9
|
+
const HIERARCHY_QUERY = "query($owner:String!,$repo:String!,$number:Int!){repository(owner:$owner,name:$repo){issue(number:$number){subIssues(first:100){nodes{state}}}}}";
|
|
10
|
+
/**
|
|
11
|
+
* Extract the issue number from a canonical `owner/repo#N` ref.
|
|
12
|
+
* @param ref - Canonical ref
|
|
13
|
+
* @returns Issue number as a string
|
|
14
|
+
*/
|
|
15
|
+
function issueNumber(ref) {
|
|
16
|
+
return ref.slice(ref.lastIndexOf("#") + 1);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse label names from a gh issue-view payload.
|
|
20
|
+
* @param value - Parsed issue JSON
|
|
21
|
+
* @returns Label names
|
|
22
|
+
*/
|
|
23
|
+
function labelNames(value) {
|
|
24
|
+
const labels = value.labels;
|
|
25
|
+
if (!Array.isArray(labels))
|
|
26
|
+
return [];
|
|
27
|
+
return labels.flatMap(label => typeof label.name === "string" ? [label.name] : []);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Count open sub-issues from the hierarchy GraphQL payload.
|
|
31
|
+
* @param value - Parsed GraphQL response
|
|
32
|
+
* @returns Number of open children
|
|
33
|
+
*/
|
|
34
|
+
function openChildrenOf(value) {
|
|
35
|
+
const nodes = value.data?.repository?.issue?.subIssues?.nodes;
|
|
36
|
+
if (!Array.isArray(nodes))
|
|
37
|
+
return 0;
|
|
38
|
+
return nodes.filter(node => node.state === "OPEN").length;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch the vendor-neutral state snapshot for one issue.
|
|
42
|
+
* @param context - Bound adapter collaborators
|
|
43
|
+
* @param ref - Canonical ref
|
|
44
|
+
* @returns Item state
|
|
45
|
+
*/
|
|
46
|
+
async function fetchState(context, ref) {
|
|
47
|
+
const number = issueNumber(ref);
|
|
48
|
+
const issueRaw = await context.execGh([
|
|
49
|
+
"issue",
|
|
50
|
+
"view",
|
|
51
|
+
number,
|
|
52
|
+
"--repo",
|
|
53
|
+
context.repository,
|
|
54
|
+
"--json",
|
|
55
|
+
"number,state,labels",
|
|
56
|
+
]);
|
|
57
|
+
const issue = JSON.parse(issueRaw);
|
|
58
|
+
const [owner, repo] = context.repository.split("/");
|
|
59
|
+
// -f passes owner/repo as raw strings; -F stays only for the integer
|
|
60
|
+
// number variable — typed -F parsing of attacker-influencable strings
|
|
61
|
+
// could coerce them into unintended JSON values.
|
|
62
|
+
const hierarchyRaw = await context.execGh([
|
|
63
|
+
"api",
|
|
64
|
+
"graphql",
|
|
65
|
+
"-f",
|
|
66
|
+
`query=${HIERARCHY_QUERY}`,
|
|
67
|
+
"-f",
|
|
68
|
+
`owner=${owner ?? ""}`,
|
|
69
|
+
"-f",
|
|
70
|
+
`repo=${repo ?? ""}`,
|
|
71
|
+
"-F",
|
|
72
|
+
`number=${number}`,
|
|
73
|
+
]);
|
|
74
|
+
return {
|
|
75
|
+
ref,
|
|
76
|
+
...deriveLabelState(labelNames(issue), context.doneStatuses),
|
|
77
|
+
openChildren: openChildrenOf(JSON.parse(hierarchyRaw)),
|
|
78
|
+
closed: issue.state === "CLOSED",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Move the issue to the target done label, removing the other done labels.
|
|
83
|
+
* @param context - Bound adapter collaborators
|
|
84
|
+
* @param ref - Canonical ref
|
|
85
|
+
* @param doneStatus - Target done label
|
|
86
|
+
*/
|
|
87
|
+
async function transition(context, ref, doneStatus) {
|
|
88
|
+
const removals = context.doneStatuses
|
|
89
|
+
.filter(status => status !== doneStatus)
|
|
90
|
+
.flatMap(status => ["--remove-label", status]);
|
|
91
|
+
await context.execGh([
|
|
92
|
+
"issue",
|
|
93
|
+
"edit",
|
|
94
|
+
issueNumber(ref),
|
|
95
|
+
"--repo",
|
|
96
|
+
context.repository,
|
|
97
|
+
"--add-label",
|
|
98
|
+
doneStatus,
|
|
99
|
+
...removals,
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find-or-update the single marker-managed comment on the issue.
|
|
104
|
+
* @param context - Bound adapter collaborators
|
|
105
|
+
* @param ref - Canonical ref
|
|
106
|
+
* @param body - Deterministic comment body
|
|
107
|
+
* @returns Upsert outcome
|
|
108
|
+
*/
|
|
109
|
+
async function upsertComment(context, ref, body) {
|
|
110
|
+
const number = issueNumber(ref);
|
|
111
|
+
// --slurp wraps each page in one top-level array; without it, multi-page
|
|
112
|
+
// output is concatenated JSON documents that JSON.parse cannot read and a
|
|
113
|
+
// marker comment past page 1 would be re-created instead of updated.
|
|
114
|
+
const listRaw = await context.execGh([
|
|
115
|
+
"api",
|
|
116
|
+
`repos/${context.repository}/issues/${number}/comments`,
|
|
117
|
+
"--paginate",
|
|
118
|
+
"--slurp",
|
|
119
|
+
]);
|
|
120
|
+
const comments = JSON.parse(listRaw).flat();
|
|
121
|
+
const existing = comments.find(comment => typeof comment.body === "string" &&
|
|
122
|
+
comment.body.startsWith(DEPLOY_STATUS_SYNC_MARKER));
|
|
123
|
+
if (existing === undefined) {
|
|
124
|
+
await context.execGh([
|
|
125
|
+
"api",
|
|
126
|
+
`repos/${context.repository}/issues/${number}/comments`,
|
|
127
|
+
"-f",
|
|
128
|
+
`body=${body}`,
|
|
129
|
+
]);
|
|
130
|
+
return "created";
|
|
131
|
+
}
|
|
132
|
+
if (existing.body === body)
|
|
133
|
+
return "unchanged";
|
|
134
|
+
await context.execGh([
|
|
135
|
+
"api",
|
|
136
|
+
`repos/${context.repository}/issues/comments/${String(existing.id)}`,
|
|
137
|
+
"-X",
|
|
138
|
+
"PATCH",
|
|
139
|
+
"-f",
|
|
140
|
+
`body=${body}`,
|
|
141
|
+
]);
|
|
142
|
+
return "updated";
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create the GitHub adapter.
|
|
146
|
+
* @param options - Repository and done vocabulary
|
|
147
|
+
* @param deps - gh executor
|
|
148
|
+
* @returns Tracker adapter over gh
|
|
149
|
+
*/
|
|
150
|
+
export function createGithubAdapter(options, deps) {
|
|
151
|
+
const context = { ...options, execGh: deps.execGh };
|
|
152
|
+
return {
|
|
153
|
+
fetchItemState: ref => fetchState(context, ref),
|
|
154
|
+
transitionToDone: (ref, doneStatus) => transition(context, ref, doneStatus),
|
|
155
|
+
upsertManagedComment: (ref, body) => upsertComment(context, ref, body),
|
|
156
|
+
closeNatively: async (ref) => {
|
|
157
|
+
await context.execGh([
|
|
158
|
+
"issue",
|
|
159
|
+
"close",
|
|
160
|
+
issueNumber(ref),
|
|
161
|
+
"--repo",
|
|
162
|
+
context.repository,
|
|
163
|
+
]);
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=deploy-status-adapter-github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-status-adapter-github.js","sourceRoot":"","sources":["../../src/cli/deploy-status-adapter-github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TrackerAdapter, TrackerAdapterDeps } from "./deploy-status-adapter-shared.js";
|
|
2
|
+
/** Construction options for {@link createJiraAdapter}. */
|
|
3
|
+
export interface JiraAdapterOptions {
|
|
4
|
+
/** Atlassian cloud id (gateway base URL for writes) */
|
|
5
|
+
readonly cloudId?: string;
|
|
6
|
+
/** Site host fallback when no cloudId is configured */
|
|
7
|
+
readonly site?: string;
|
|
8
|
+
/** Login fallback when `JIRA_LOGIN` is unset */
|
|
9
|
+
readonly email?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create the Jira adapter.
|
|
13
|
+
* @param options - Cloud id / site / login fallback
|
|
14
|
+
* @param deps - Injectable fetch and env
|
|
15
|
+
* @returns Tracker adapter over the Jira REST API
|
|
16
|
+
*/
|
|
17
|
+
export declare function createJiraAdapter(options: JiraAdapterOptions, deps?: TrackerAdapterDeps): TrackerAdapter;
|
|
18
|
+
//# sourceMappingURL=deploy-status-adapter-jira.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-status-adapter-jira.d.ts","sourceRoot":"","sources":["../../src/cli/deploy-status-adapter-jira.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EACnB,MAAM,mCAAmC,CAAC;AAG3C,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAuQD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,IAAI,GAAE,kBAAuB,GAC5B,cAAc,CAUhB"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jira tracker adapter for deploy-status-sync over the Jira Cloud REST API.
|
|
3
|
+
*
|
|
4
|
+
* Contract-tested only in DSS-2 (unit tests inject a recording fetch); DSS-7
|
|
5
|
+
* flips it live through the same factory. Writes go through the cloudId
|
|
6
|
+
* gateway (`api.atlassian.com/ex/jira/<cloudId>`); transitions resolve the
|
|
7
|
+
* transition id first, then POST it. Credentials travel only in the Basic
|
|
8
|
+
* `Authorization` header — never in argv. Native closure is a no-op: in Jira
|
|
9
|
+
* the terminal done-category status IS closure.
|
|
10
|
+
* @module cli/deploy-status-adapter-jira
|
|
11
|
+
*/
|
|
12
|
+
import { DEPLOY_STATUS_SYNC_MARKER, } from "../core/deploy-status-transition.js";
|
|
13
|
+
import { getProcessEnv } from "./update-check.js";
|
|
14
|
+
/**
|
|
15
|
+
* Build the ADF document for a managed comment body: one paragraph node per
|
|
16
|
+
* line — ADF text nodes must not carry raw newline characters (Jira rejects
|
|
17
|
+
* or mangles them), so the body is split on `\n` and a blank line becomes an
|
|
18
|
+
* empty paragraph.
|
|
19
|
+
* @param text - Plain comment text (may span multiple lines)
|
|
20
|
+
* @returns ADF document
|
|
21
|
+
*/
|
|
22
|
+
function adfDocument(text) {
|
|
23
|
+
return {
|
|
24
|
+
type: "doc",
|
|
25
|
+
version: 1,
|
|
26
|
+
content: text.split("\n").map(line => ({
|
|
27
|
+
type: "paragraph",
|
|
28
|
+
content: line.length === 0 ? [] : [{ type: "text", text: line }],
|
|
29
|
+
})),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract the first text node from an ADF comment body.
|
|
34
|
+
* @param body - ADF body value
|
|
35
|
+
* @returns The first text run, or empty string
|
|
36
|
+
*/
|
|
37
|
+
function adfFirstText(body) {
|
|
38
|
+
const doc = body;
|
|
39
|
+
const text = doc.content?.[0]?.content?.[0]?.text;
|
|
40
|
+
return typeof text === "string" ? text : "";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Project an ADF comment body onto plain text: text nodes joined per
|
|
44
|
+
* paragraph, paragraphs joined with newlines. This is the unchanged-check
|
|
45
|
+
* comparison basis — Jira round-trips ADF with its own key order and extra
|
|
46
|
+
* fields (attrs, marks), so a raw JSON comparison would report a semantic
|
|
47
|
+
* no-change as different and issue a redundant PUT on every run.
|
|
48
|
+
* @param body - ADF body value
|
|
49
|
+
* @returns Plain-text projection of the document
|
|
50
|
+
*/
|
|
51
|
+
function adfPlainText(body) {
|
|
52
|
+
const doc = body;
|
|
53
|
+
return (doc.content ?? [])
|
|
54
|
+
.map(paragraph => (paragraph.content ?? [])
|
|
55
|
+
.map(node => (typeof node.text === "string" ? node.text : ""))
|
|
56
|
+
.join(""))
|
|
57
|
+
.join("\n");
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether a Jira status payload sits in the done category.
|
|
61
|
+
* @param status - Jira status field value
|
|
62
|
+
* @returns True for done-category statuses
|
|
63
|
+
*/
|
|
64
|
+
function isDoneCategory(status) {
|
|
65
|
+
const key = status.statusCategory
|
|
66
|
+
?.key;
|
|
67
|
+
return key === "done";
|
|
68
|
+
}
|
|
69
|
+
/** The only host shape the site fallback may target. */
|
|
70
|
+
const SITE_HOST_PATTERN = /^[a-z0-9-]+\.atlassian\.net$/i;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve the REST base URL: the cloudId gateway when configured, else the
|
|
73
|
+
* `atlassian.site` fallback — which must be a bare `*.atlassian.net` host.
|
|
74
|
+
* Anything else (paths, foreign hosts) is rejected decision-readably before
|
|
75
|
+
* any request is made, so a poisoned config value cannot steer credentialed
|
|
76
|
+
* requests to an attacker-chosen server.
|
|
77
|
+
* @param options - Cloud id / site fallback
|
|
78
|
+
* @returns Base URL, or undefined when neither source is configured
|
|
79
|
+
*/
|
|
80
|
+
function resolveBaseUrl(options) {
|
|
81
|
+
if (options.cloudId !== undefined) {
|
|
82
|
+
return `https://api.atlassian.com/ex/jira/${encodeURIComponent(options.cloudId)}`;
|
|
83
|
+
}
|
|
84
|
+
const site = (options.site ?? "")
|
|
85
|
+
.replace(/^https?:\/\//, "")
|
|
86
|
+
.replace(/\/$/, "");
|
|
87
|
+
if (site.length === 0)
|
|
88
|
+
return undefined;
|
|
89
|
+
if (!SITE_HOST_PATTERN.test(site)) {
|
|
90
|
+
throw new Error(`Invalid atlassian.site "${options.site ?? ""}" in .lisa.config.json: expected a bare "<site>.atlassian.net" host. Set atlassian.cloudId (preferred) or fix atlassian.site.`);
|
|
91
|
+
}
|
|
92
|
+
return `https://${site}`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build the authenticated REST transport (Basic auth header only — the
|
|
96
|
+
* token never reaches argv or the URL).
|
|
97
|
+
* @param options - Cloud id / site / login fallback
|
|
98
|
+
* @param deps - Injectable fetch and env
|
|
99
|
+
* @returns Bound transport
|
|
100
|
+
*/
|
|
101
|
+
function createRequest(options, deps) {
|
|
102
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
103
|
+
return async (path, init = {}) => {
|
|
104
|
+
const env = deps.env ?? getProcessEnv();
|
|
105
|
+
const token = env.JIRA_API_TOKEN ?? env.ATLASSIAN_API_TOKEN;
|
|
106
|
+
const login = env.JIRA_LOGIN ?? options.email;
|
|
107
|
+
const baseUrl = resolveBaseUrl(options);
|
|
108
|
+
if (token === undefined || login === undefined || baseUrl === undefined) {
|
|
109
|
+
throw new Error("Jira credentials not found: set JIRA_API_TOKEN or ATLASSIAN_API_TOKEN (plus JIRA_LOGIN or atlassian.email) and configure atlassian.cloudId");
|
|
110
|
+
}
|
|
111
|
+
const basic = Buffer.from(`${login}:${token}`).toString("base64");
|
|
112
|
+
const response = await fetchImpl(`${baseUrl}${path}`, {
|
|
113
|
+
method: init.method ?? "GET",
|
|
114
|
+
headers: {
|
|
115
|
+
Authorization: `Basic ${basic}`,
|
|
116
|
+
Accept: "application/json",
|
|
117
|
+
...(init.body === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { "Content-Type": "application/json" }),
|
|
120
|
+
},
|
|
121
|
+
...(init.body === undefined ? {} : { body: init.body }),
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
throw new Error(`Jira request ${init.method ?? "GET"} ${path} failed with HTTP ${String(response.status)}`);
|
|
125
|
+
}
|
|
126
|
+
const text = await response.text();
|
|
127
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Fetch the vendor-neutral state snapshot for one issue.
|
|
132
|
+
* @param request - Bound transport
|
|
133
|
+
* @param ref - Issue key
|
|
134
|
+
* @returns Item state
|
|
135
|
+
*/
|
|
136
|
+
async function fetchState(request, ref) {
|
|
137
|
+
const issue = (await request(`/rest/api/3/issue/${ref}?fields=status,issuetype,subtasks`));
|
|
138
|
+
const status = issue.fields?.status;
|
|
139
|
+
const type = issue.fields?.issuetype?.name;
|
|
140
|
+
const openChildren = (issue.fields?.subtasks ?? []).filter(subtask => !isDoneCategory(subtask.fields?.status)).length;
|
|
141
|
+
return {
|
|
142
|
+
ref,
|
|
143
|
+
...(type === undefined ? {} : { type }),
|
|
144
|
+
openChildren,
|
|
145
|
+
...(status?.name === undefined ? {} : { currentStatus: status.name }),
|
|
146
|
+
closed: isDoneCategory(status),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Resolve the transition id reaching the done status, then POST it.
|
|
151
|
+
* @param request - Bound transport
|
|
152
|
+
* @param ref - Issue key
|
|
153
|
+
* @param doneStatus - Target status name (config-sourced)
|
|
154
|
+
*/
|
|
155
|
+
async function transition(request, ref, doneStatus) {
|
|
156
|
+
const payload = (await request(`/rest/api/3/issue/${ref}/transitions`));
|
|
157
|
+
const match = (payload.transitions ?? []).find(candidate => (candidate.to?.name ?? "").toLowerCase() === doneStatus.toLowerCase());
|
|
158
|
+
if (match?.id === undefined) {
|
|
159
|
+
throw new Error(`Jira issue ${ref} has no transition reaching "${doneStatus}" — fix the workflow or jira.workflow.done`);
|
|
160
|
+
}
|
|
161
|
+
await request(`/rest/api/3/issue/${ref}/transitions`, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
body: JSON.stringify({ transition: { id: match.id } }),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Find-or-update the single marker-managed ADF comment on the issue.
|
|
168
|
+
* @param request - Bound transport
|
|
169
|
+
* @param ref - Issue key
|
|
170
|
+
* @param body - Deterministic plain-text comment body
|
|
171
|
+
* @returns Upsert outcome
|
|
172
|
+
*/
|
|
173
|
+
async function upsertComment(request, ref, body) {
|
|
174
|
+
// Bounded page, newest first: the marker comment is recent by
|
|
175
|
+
// construction. Live multi-page walking is DSS-7 acceptance scope.
|
|
176
|
+
const payload = (await request(`/rest/api/3/issue/${ref}/comment?maxResults=100&orderBy=-created`));
|
|
177
|
+
const existing = (payload.comments ?? []).find(comment => adfFirstText(comment.body).startsWith(DEPLOY_STATUS_SYNC_MARKER));
|
|
178
|
+
const doc = adfDocument(body);
|
|
179
|
+
if (existing === undefined) {
|
|
180
|
+
await request(`/rest/api/3/issue/${ref}/comment`, {
|
|
181
|
+
method: "POST",
|
|
182
|
+
body: JSON.stringify({ body: doc }),
|
|
183
|
+
});
|
|
184
|
+
return "created";
|
|
185
|
+
}
|
|
186
|
+
// Compare on the plain-text projection, not raw JSON — the server-stored
|
|
187
|
+
// ADF is normalized (key order, attrs/marks defaults) and would never
|
|
188
|
+
// byte-match the freshly built document.
|
|
189
|
+
if (adfPlainText(existing.body) === body) {
|
|
190
|
+
return "unchanged";
|
|
191
|
+
}
|
|
192
|
+
await request(`/rest/api/3/issue/${ref}/comment/${existing.id ?? ""}`, {
|
|
193
|
+
method: "PUT",
|
|
194
|
+
body: JSON.stringify({ body: doc }),
|
|
195
|
+
});
|
|
196
|
+
return "updated";
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Create the Jira adapter.
|
|
200
|
+
* @param options - Cloud id / site / login fallback
|
|
201
|
+
* @param deps - Injectable fetch and env
|
|
202
|
+
* @returns Tracker adapter over the Jira REST API
|
|
203
|
+
*/
|
|
204
|
+
export function createJiraAdapter(options, deps = {}) {
|
|
205
|
+
const request = createRequest(options, deps);
|
|
206
|
+
return {
|
|
207
|
+
fetchItemState: ref => fetchState(request, ref),
|
|
208
|
+
transitionToDone: (ref, doneStatus) => transition(request, ref, doneStatus),
|
|
209
|
+
upsertManagedComment: (ref, body) => upsertComment(request, ref, body),
|
|
210
|
+
// Jira has no separate close: the terminal done-category status IS the
|
|
211
|
+
// native closure, so this is deliberately a zero-request no-op.
|
|
212
|
+
closeNatively: () => Promise.resolve(),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=deploy-status-adapter-jira.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-status-adapter-jira.js","sourceRoot":"","sources":["../../src/cli/deploy-status-adapter-jira.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TrackerAdapter, type TrackerAdapterDeps } from "./deploy-status-adapter-shared.js";
|
|
2
|
+
/** Construction options for {@link createLinearAdapter}. */
|
|
3
|
+
export interface LinearAdapterOptions {
|
|
4
|
+
/** Linear workspace slug (credential scoping + keychain account) */
|
|
5
|
+
readonly workspace: string;
|
|
6
|
+
/** Ladder done vocabulary, lowest rung first (config-sourced) */
|
|
7
|
+
readonly doneStatuses: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create the Linear adapter.
|
|
11
|
+
* @param options - Workspace and done vocabulary
|
|
12
|
+
* @param deps - Injectable fetch, env, and secret reader
|
|
13
|
+
* @returns Tracker adapter over the Linear GraphQL API
|
|
14
|
+
*/
|
|
15
|
+
export declare function createLinearAdapter(options: LinearAdapterOptions, deps?: TrackerAdapterDeps): TrackerAdapter;
|
|
16
|
+
//# sourceMappingURL=deploy-status-adapter-linear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-status-adapter-linear.d.ts","sourceRoot":"","sources":["../../src/cli/deploy-status-adapter-linear.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,mCAAmC,CAAC;AAG3C,4DAA4D;AAC5D,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAqQD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,GAAE,kBAAuB,GAC5B,cAAc,CAWhB"}
|