@codyswann/lisa 2.293.0 → 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.
Files changed (123) hide show
  1. package/all/copy-overwrite/scripts/lisa-work-item.mjs +12 -3
  2. package/dist/cli/deploy-status-adapter-github.d.ts +20 -0
  3. package/dist/cli/deploy-status-adapter-github.d.ts.map +1 -0
  4. package/dist/cli/deploy-status-adapter-github.js +167 -0
  5. package/dist/cli/deploy-status-adapter-github.js.map +1 -0
  6. package/dist/cli/deploy-status-adapter-jira.d.ts +18 -0
  7. package/dist/cli/deploy-status-adapter-jira.d.ts.map +1 -0
  8. package/dist/cli/deploy-status-adapter-jira.js +215 -0
  9. package/dist/cli/deploy-status-adapter-jira.js.map +1 -0
  10. package/dist/cli/deploy-status-adapter-linear.d.ts +16 -0
  11. package/dist/cli/deploy-status-adapter-linear.d.ts.map +1 -0
  12. package/dist/cli/deploy-status-adapter-linear.js +204 -0
  13. package/dist/cli/deploy-status-adapter-linear.js.map +1 -0
  14. package/dist/cli/deploy-status-adapter-shared.d.ts +57 -0
  15. package/dist/cli/deploy-status-adapter-shared.d.ts.map +1 -0
  16. package/dist/cli/deploy-status-adapter-shared.js +62 -0
  17. package/dist/cli/deploy-status-adapter-shared.js.map +1 -0
  18. package/dist/cli/deploy-status-adapter.d.ts +49 -0
  19. package/dist/cli/deploy-status-adapter.d.ts.map +1 -0
  20. package/dist/cli/deploy-status-adapter.js +87 -0
  21. package/dist/cli/deploy-status-adapter.js.map +1 -0
  22. package/dist/cli/deploy-status-refs.d.ts +70 -0
  23. package/dist/cli/deploy-status-refs.d.ts.map +1 -0
  24. package/dist/cli/deploy-status-refs.js +195 -0
  25. package/dist/cli/deploy-status-refs.js.map +1 -0
  26. package/dist/cli/deploy-status-sync-cmd.d.ts +23 -0
  27. package/dist/cli/deploy-status-sync-cmd.d.ts.map +1 -0
  28. package/dist/cli/deploy-status-sync-cmd.js +75 -0
  29. package/dist/cli/deploy-status-sync-cmd.js.map +1 -0
  30. package/dist/cli/deploy-status-sync-engine.d.ts +49 -0
  31. package/dist/cli/deploy-status-sync-engine.d.ts.map +1 -0
  32. package/dist/cli/deploy-status-sync-engine.js +214 -0
  33. package/dist/cli/deploy-status-sync-engine.js.map +1 -0
  34. package/dist/cli/deploy-status-sync-exec.d.ts +73 -0
  35. package/dist/cli/deploy-status-sync-exec.d.ts.map +1 -0
  36. package/dist/cli/deploy-status-sync-exec.js +95 -0
  37. package/dist/cli/deploy-status-sync-exec.js.map +1 -0
  38. package/dist/cli/gate-commands.d.ts +3 -1
  39. package/dist/cli/gate-commands.d.ts.map +1 -1
  40. package/dist/cli/gate-commands.js +26 -0
  41. package/dist/cli/gate-commands.js.map +1 -1
  42. package/dist/cli/index.d.ts +2 -7
  43. package/dist/cli/index.d.ts.map +1 -1
  44. package/dist/cli/index.js +4 -43
  45. package/dist/cli/index.js.map +1 -1
  46. package/dist/cli/kane-commands.d.ts +21 -0
  47. package/dist/cli/kane-commands.d.ts.map +1 -0
  48. package/dist/cli/kane-commands.js +44 -0
  49. package/dist/cli/kane-commands.js.map +1 -0
  50. package/dist/cli/update-check.d.ts +8 -0
  51. package/dist/cli/update-check.d.ts.map +1 -1
  52. package/dist/cli/update-check.js +4 -2
  53. package/dist/cli/update-check.js.map +1 -1
  54. package/dist/core/deploy-status-sync.d.ts +15 -0
  55. package/dist/core/deploy-status-sync.d.ts.map +1 -1
  56. package/dist/core/deploy-status-sync.js +57 -19
  57. package/dist/core/deploy-status-sync.js.map +1 -1
  58. package/dist/core/deploy-status-transition.d.ts +97 -0
  59. package/dist/core/deploy-status-transition.d.ts.map +1 -0
  60. package/dist/core/deploy-status-transition.js +134 -0
  61. package/dist/core/deploy-status-transition.js.map +1 -0
  62. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  63. package/dist/core/upstream-evidence-manifest.js +24 -3
  64. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  65. package/package.json +1 -1
  66. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  68. package/plugins/lisa/rules/eager/config-resolution.md +3 -2
  69. package/plugins/lisa/rules/reference/config-resolution.md +13 -1
  70. package/plugins/lisa-agy/plugin.json +1 -1
  71. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  73. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  74. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-copilot/rules/eager/config-resolution.md +3 -2
  78. package/plugins/lisa-copilot/rules/reference/config-resolution.md +13 -1
  79. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +13 -1
  81. package/plugins/lisa-cursor/rules/config-resolution.mdc +3 -2
  82. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  84. package/plugins/lisa-expo-agy/plugin.json +1 -1
  85. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  89. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  90. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  94. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  95. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  99. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  100. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  104. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  105. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  109. package/plugins/lisa-rails-agy/plugin.json +1 -1
  110. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  114. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  115. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  116. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  119. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  120. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  121. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  122. package/plugins/src/base/rules/eager/config-resolution.md +3 -2
  123. package/plugins/src/base/rules/reference/config-resolution.md +13 -1
@@ -426,15 +426,24 @@ function namesFrom(value) {
426
426
  }
427
427
 
428
428
  function assertRepoScope(ref, contract, labels, components = []) {
429
- const expected = `repo:${contract.identityRepo}`.toLowerCase();
429
+ // #1957: mirror the intake-side scoping rule uniformly across trackers
430
+ // (plugins/lisa/rules/reference/config-resolution.md:949,:968): a work item
431
+ // is repo-scoped by the label `repo:<name>` OR the bare `<name>` label
432
+ // (Sentry-provenance items carry only the bare repo name). The match is the
433
+ // exact repo short name, case-insensitive via namesFrom's lowercasing —
434
+ // never substring or prefix. Jira additionally accepts a component equal to
435
+ // the bare name.
436
+ const bare = contract.identityRepo.toLowerCase();
437
+ const expected = `repo:${bare}`;
430
438
  const labelNames = namesFrom(labels);
431
439
  const componentNames = namesFrom(components);
432
440
  if (
433
441
  !labelNames.includes(expected) &&
434
- !componentNames.includes(contract.identityRepo.toLowerCase())
442
+ !labelNames.includes(bare) &&
443
+ !componentNames.includes(bare)
435
444
  ) {
436
445
  throw new TrackingError(
437
- `Work item ${ref} is not scoped to repository ${contract.identityRepo}; require label ${expected}`
446
+ `Work item ${ref} is not scoped to repository ${contract.identityRepo}; require label ${expected} or bare label ${bare}`
438
447
  );
439
448
  }
440
449
  }
@@ -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"}