ticketlens 0.38.50 → 0.38.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticketlens",
3
- "version": "0.38.50",
3
+ "version": "0.38.51",
4
4
  "description": "Jira CLI for developers — fetch ticket context, triage your queue, and stop tab-switching. Zero dependencies, all local.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -125,7 +125,10 @@ export function createJiraAdapter(conn, { fetcher = globalThis.fetch } = {}) {
125
125
  * Always re-fetches link types fresh and resolves `typeName` against
126
126
  * them before executing — a caller can never blind-POST a stale or
127
127
  * guessed type name, same principle as transition().
128
- * sourceKey is the outwardIssue, targetKey is the inwardIssue — direction matters.
128
+ * sourceKey ends up performing the type's outward verb onto targetKey
129
+ * (e.g. "sourceKey duplicates targetKey") — see postIssueLink's own
130
+ * doc comment in jira-client.mjs for why its POST body's field names
131
+ * don't map the way you'd guess from Jira's GET-response convention.
129
132
  */
130
133
  async linkTo(sourceKey, targetKey, typeName, opts = {}) {
131
134
  const types = await getIssueLinkTypes({ ...base, ...opts });
@@ -544,10 +544,20 @@ export async function getIssueLinkTypes(opts = {}) {
544
544
  }
545
545
 
546
546
  /**
547
- * Creates a link between two issues. `sourceKey` is the outwardIssue (the
548
- * subject of the type's outward verb, e.g. "Duplicates"), `targetKey` is
549
- * the inwardIssue — direction matters and is the caller's responsibility
550
- * to get right (ticket-command.mjs documents the convention).
547
+ * Creates a link between two issues so `sourceKey` performs the type's
548
+ * outward verb onto `targetKey` (e.g. "sourceKey duplicates targetKey").
549
+ *
550
+ * The POST body's `outwardIssue`/`inwardIssue` keys are the REVERSE of what
551
+ * you'd expect from the GET /issue response's self-referential convention
552
+ * (where an issue's OWN `issuelinks` entry uses `outwardIssue` to mean "I am
553
+ * the outward/performing side") — sending `outwardIssue: sourceKey` there
554
+ * produces the OPPOSITE real relationship. Live-verified against two real
555
+ * Jira Cloud instances, cross-checked from both linked issues' own GET
556
+ * responses, reproduced twice independently (Blocks and Duplicate types,
557
+ * both argument orders) — not a guess, not doc-derived. This is backlog
558
+ * #31's actual root cause: every prior "direction inverted" report was
559
+ * real, and no unit test caught it because mocked HTTP calls can only
560
+ * assert the request shape, never Jira's real interpretation of it.
551
561
  */
552
562
  export async function postIssueLink(sourceKey, targetKey, typeName, opts = {}) {
553
563
  const { env = process.env, fetcher = globalThis.fetch, lookup = defaultLookupFor(fetcher), apiVersion = 2, timeoutMs = 10_000, allowPrivateIp = false } = opts;
@@ -558,7 +568,7 @@ export async function postIssueLink(sourceKey, targetKey, typeName, opts = {}) {
558
568
  const fetchOpts = {
559
569
  method: 'POST',
560
570
  headers: { ...buildAuthHeader(env), 'Content-Type': 'application/json' },
561
- body: JSON.stringify({ type: { name: typeName }, outwardIssue: { key: sourceKey }, inwardIssue: { key: targetKey } }),
571
+ body: JSON.stringify({ type: { name: typeName }, outwardIssue: { key: targetKey }, inwardIssue: { key: sourceKey } }),
562
572
  };
563
573
  if (timeoutMs) fetchOpts.signal = AbortSignal.timeout(timeoutMs);
564
574