@relayfile/adapter-linear 0.3.12 → 0.3.15
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/discovery/linear/.adapter.md +62 -1
- package/discovery/linear/projects/.create.example.json +6 -0
- package/discovery/linear/projects/.schema.json +147 -0
- package/discovery/linear/projects/{projectId}/add-issues.json/.create.example.json +5 -0
- package/discovery/linear/projects/{projectId}/add-issues.json/.schema.json +88 -0
- package/discovery/linear/projects/{projectId}/meta.json/.create.example.json +3 -0
- package/discovery/linear/projects/{projectId}/meta.json/.schema.json +121 -0
- package/dist/__tests__/aliases.test.js +8 -8
- package/dist/__tests__/aliases.test.js.map +1 -1
- package/dist/__tests__/emit-auxiliary-files.test.js +144 -9
- package/dist/__tests__/emit-auxiliary-files.test.js.map +1 -1
- package/dist/__tests__/index-emission.test.js +16 -4
- package/dist/__tests__/index-emission.test.js.map +1 -1
- package/dist/__tests__/linear-adapter.test.js +7 -7
- package/dist/__tests__/linear-adapter.test.js.map +1 -1
- package/dist/__tests__/path-mapper.test.js +12 -1
- package/dist/__tests__/path-mapper.test.js.map +1 -1
- package/dist/emit-auxiliary-files.d.ts +16 -7
- package/dist/emit-auxiliary-files.d.ts.map +1 -1
- package/dist/emit-auxiliary-files.js +113 -13
- package/dist/emit-auxiliary-files.js.map +1 -1
- package/dist/index-emitter.d.ts +2 -1
- package/dist/index-emitter.d.ts.map +1 -1
- package/dist/index-emitter.js +4 -1
- package/dist/index-emitter.js.map +1 -1
- package/dist/layout-prompt.d.ts +1 -1
- package/dist/layout-prompt.d.ts.map +1 -1
- package/dist/layout-prompt.js +13 -3
- package/dist/layout-prompt.js.map +1 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +15 -3
- package/dist/layout.js.map +1 -1
- package/dist/layout.test.js +3 -0
- package/dist/layout.test.js.map +1 -1
- package/dist/linear-adapter.d.ts.map +1 -1
- package/dist/linear-adapter.js +58 -9
- package/dist/linear-adapter.js.map +1 -1
- package/dist/path-mapper.d.ts +15 -1
- package/dist/path-mapper.d.ts.map +1 -1
- package/dist/path-mapper.js +39 -0
- package/dist/path-mapper.js.map +1 -1
- package/dist/queries.d.ts +15 -7
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +14 -0
- package/dist/queries.js.map +1 -1
- package/dist/resources.d.ts +21 -0
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +24 -0
- package/dist/resources.js.map +1 -1
- package/dist/types.d.ts +34 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/writeback.d.ts +4 -1
- package/dist/writeback.d.ts.map +1 -1
- package/dist/writeback.js +145 -6
- package/dist/writeback.js.map +1 -1
- package/dist/writeback.test.js +122 -5
- package/dist/writeback.test.js.map +1 -1
- package/package.json +2 -2
package/dist/index-emitter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { linearCyclesIndexPath, linearCommentsIndexPath, linearIssuesIndexPath, linearMilestonesIndexPath, linearProjectsIndexPath, linearRootIndexPath, linearRoadmapsIndexPath, linearTeamsIndexPath, linearUsersIndexPath, } from './path-mapper.js';
|
|
1
|
+
import { linearCyclesIndexPath, linearCommentsIndexPath, linearIssuesIndexPath, linearMilestonesIndexPath, linearProjectsIndexPath, linearRootIndexPath, linearRoadmapsIndexPath, linearStatesIndexPath, linearTeamsIndexPath, linearUsersIndexPath, } from './path-mapper.js';
|
|
2
2
|
/**
|
|
3
3
|
* Build `/linear/_index.json` — a static listing of top-level resource
|
|
4
4
|
* roots the Linear adapter exposes. Mirrors the slack pattern so an agent
|
|
@@ -10,6 +10,7 @@ export function buildLinearRootIndexFile(rows = [
|
|
|
10
10
|
{ id: 'teams', title: 'Teams' },
|
|
11
11
|
{ id: 'users', title: 'Users' },
|
|
12
12
|
{ id: 'projects', title: 'Projects' },
|
|
13
|
+
{ id: 'states', title: 'Workflow States' },
|
|
13
14
|
{ id: 'cycles', title: 'Cycles' },
|
|
14
15
|
{ id: 'milestones', title: 'Milestones' },
|
|
15
16
|
{ id: 'roadmaps', title: 'Roadmaps' },
|
|
@@ -40,6 +41,8 @@ function indexPathForBucket(bucket) {
|
|
|
40
41
|
return linearMilestonesIndexPath();
|
|
41
42
|
case 'projects':
|
|
42
43
|
return linearProjectsIndexPath();
|
|
44
|
+
case 'states':
|
|
45
|
+
return linearStatesIndexPath();
|
|
43
46
|
case 'roadmaps':
|
|
44
47
|
return linearRoadmapsIndexPath();
|
|
45
48
|
case 'users':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-emitter.js","sourceRoot":"","sources":["../src/index-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index-emitter.js","sourceRoot":"","sources":["../src/index-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAyB1B;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA6B;IAC3B,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;IACjC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;IACrC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAC/B,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAC/B,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;IACrC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC1C,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;IACjC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IACzC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;CACtC;IAED,OAAO;QACL,IAAI,EAAE,mBAAmB,EAAE;QAC3B,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI;KACrC,CAAC;AACJ,CAAC;AAcD,MAAM,UAAU,oBAAoB,CAClC,MAAyB,EACzB,IAAqD;IAErD,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO;QACL,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC;QAChC,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAyB;IACnD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,qBAAqB,EAAE,CAAC;QACjC,KAAK,UAAU;YACb,OAAO,uBAAuB,EAAE,CAAC;QACnC,KAAK,QAAQ;YACX,OAAO,qBAAqB,EAAE,CAAC;QACjC,KAAK,YAAY;YACf,OAAO,yBAAyB,EAAE,CAAC;QACrC,KAAK,UAAU;YACb,OAAO,uBAAuB,EAAE,CAAC;QACnC,KAAK,QAAQ;YACX,OAAO,qBAAqB,EAAE,CAAC;QACjC,KAAK,UAAU;YACb,OAAO,uBAAuB,EAAE,CAAC;QACnC,KAAK,OAAO;YACV,OAAO,oBAAoB,EAAE,CAAC;QAChC,KAAK,OAAO;YACV,OAAO,oBAAoB,EAAE,CAAC;IAClC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAyB;IACjD,OAAO,CAAC,IAA8C,EAAE,KAA+C,EAAU,EAAE;QACjH,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/layout-prompt.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LINEAR_LAYOUT_PROMPT = "# Linear Mount Layout\n\nAlways run `ls` before constructing a path. PR 0 standardizes human-readable leaf names to `<sanitized-name>__<id>`, so consumers should inspect the live directory instead of guessing a filename.\n\n## Tree\n\n`/linear/LAYOUT.md` is this guide.\n`/linear/issues/`, `/linear/comments/`, `/linear/users/`, `/linear/teams/`, `/linear/projects/`, `/linear/cycles/`, `/linear/milestones/`, and `/linear/roadmaps/` each own their canonical JSON records plus a sibling `_index.json`.\n`/linear/comments/<name>__<id>/meta.json` is the canonical comment record (a directory record, so per-comment children such as reactions or threaded replies can nest under `comments/<name>__<id>/` without a file/directory collision).\n\nIssue lookups: `/linear/issues/by-uuid/<uuid>.json` is the stable anchor (always emitted, keyed on the Linear UUID). `/linear/issues/by-id/<TEAM-123>.json` is the human-readable lookup keyed on the Linear identifier (only emitted when the issue has one). `/linear/issues/by-title/<slug>.json`, `/linear/issues/by-state/<state>/<TEAM-123>.json`, `/linear/issues/by-assignee/<user-id>/<TEAM-123>.json`, `/linear/issues/by-creator/<user-id>/<TEAM-123>.json`, `/linear/issues/by-priority/<priority>/<TEAM-123>.json`, and `/linear/issues/by-edited/YYYY-MM-DD/<issue-uuid>.json` are additional lookups. The edited-date bucket is formatted as `YYYY-MM-DD` and uses the first available timestamp in this order: `updatedAt`, `updated_at`, `completedAt`, `canceledAt`, `createdAt`, then `created_at`.\n\nWritable resources advertise sibling schemas and create examples at `discovery/linear/issues/.schema.json`, `discovery/linear/issues/.create.example.json`, `discovery/linear/issues/{issueId}/comments/.schema.json`,
|
|
1
|
+
export declare const LINEAR_LAYOUT_PROMPT = "# Linear Mount Layout\n\nAlways run `ls` before constructing a path. PR 0 standardizes human-readable leaf names to `<sanitized-name>__<id>`, so consumers should inspect the live directory instead of guessing a filename.\n\n## Tree\n\n`/linear/LAYOUT.md` is this guide.\n`/linear/issues/`, `/linear/comments/`, `/linear/users/`, `/linear/teams/`, `/linear/projects/`, `/linear/states/`, `/linear/cycles/`, `/linear/milestones/`, and `/linear/roadmaps/` each own their canonical JSON records plus a sibling `_index.json`.\n`/linear/comments/<name>__<id>/meta.json` is the canonical comment record (a directory record, so per-comment children such as reactions or threaded replies can nest under `comments/<name>__<id>/` without a file/directory collision).\n`/linear/projects/<uuid>/meta.json` is the canonical project record. The legacy flat `/linear/projects/<uuid>.json` path is not written by current mirrors.\n\nIssue lookups: `/linear/issues/by-uuid/<uuid>.json` is the stable anchor (always emitted, keyed on the Linear UUID). `/linear/issues/by-id/<TEAM-123>.json` is the human-readable lookup keyed on the Linear identifier (only emitted when the issue has one). `/linear/issues/by-title/<slug>.json`, `/linear/issues/by-state/<state>/<TEAM-123>.json`, `/linear/issues/by-assignee/<user-id>/<TEAM-123>.json`, `/linear/issues/by-creator/<user-id>/<TEAM-123>.json`, `/linear/issues/by-priority/<priority>/<TEAM-123>.json`, and `/linear/issues/by-edited/YYYY-MM-DD/<issue-uuid>.json` are additional lookups. The edited-date bucket is formatted as `YYYY-MM-DD` and uses the first available timestamp in this order: `updatedAt`, `updated_at`, `completedAt`, `canceledAt`, `createdAt`, then `created_at`.\n\nProject lookups: `/linear/projects/by-id/<uuid>.json` is the stable project id lookup, `/linear/projects/by-name/<slug>.json` resolves a project by name, `/linear/projects/by-state/<backlog|planned|started|paused|completed|canceled>/<uuid>.json` groups by Linear project state, and `/linear/projects/by-team/<team-uuid>/<project-uuid>.json` is emitted once per team on multi-team projects.\n\nWritable resources advertise sibling schemas and create examples at `discovery/linear/issues/.schema.json`, `discovery/linear/issues/.create.example.json`, `discovery/linear/issues/{issueId}/comments/.schema.json`, `discovery/linear/issues/{issueId}/comments/.create.example.json`, `discovery/linear/projects/.schema.json`, `discovery/linear/projects/.create.example.json`, `discovery/linear/projects/{projectId}/meta.json/.schema.json`, `discovery/linear/projects/{projectId}/meta.json/.create.example.json`, `discovery/linear/projects/{projectId}/add-issues.json/.schema.json`, and `discovery/linear/projects/{projectId}/add-issues.json/.create.example.json`.\n\n## Indexes\n\n`/linear/issues/_index.json` rows use:\n\n```json\n{ \"id\": \"<id>\", \"title\": \"<human-readable>\", \"updated\": \"<iso8601>\", \"identifier\": \"<TEAM-123>\", \"state\": \"<state name>\" }\n```\n\n`/linear/comments/_index.json`, `/linear/users/_index.json`, `/linear/teams/_index.json`, `/linear/projects/_index.json`, `/linear/states/_index.json`, `/linear/cycles/_index.json`, `/linear/milestones/_index.json`, and `/linear/roadmaps/_index.json` use:\n\n```json\n{ \"id\": \"<id>\", \"title\": \"<human-readable>\", \"updated\": \"<iso8601>\" }\n```\n\n## JSONL And Querying\n\nLinear does not emit JSONL in this adapter today. Comments are individual `comments/<name>__<id>/meta.json` directory records rather than `comments.jsonl`.\n\nExamples:\n\n```bash\nls /linear/issues\njq '.[0]' /linear/issues/_index.json\njq '.[] | {identifier, state, title}' /linear/issues/_index.json\nls /linear/issues/by-assignee\nls /linear/issues/by-priority\nls /linear/issues/by-edited/2026-05-12\njq '.identifier' /linear/issues/by-edited/2026-05-12/11111111-1111-1111-1111-111111111111.json\njq '.[0]' /linear/projects/_index.json\nls /linear/projects/by-name\nls /linear/projects/by-state/started\njq '.payload.id' /linear/projects/by-team/22222222-2222-2222-2222-222222222222/11111111-1111-1111-1111-111111111111.json\njq '.[0]' /linear/states/_index.json\njq '.required' discovery/linear/issues/.schema.json\ncat discovery/linear/projects/.create.example.json\ncat discovery/linear/projects/{projectId}/add-issues.json/.create.example.json\nls discovery/linear/issues/{issueId}/comments\ngrep -R \"ENG-\" /linear/comments\n```\n";
|
|
2
2
|
export declare function linearLayoutPromptFile(): {
|
|
3
3
|
path: string;
|
|
4
4
|
contentType: "text/markdown; charset=utf-8";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-prompt.d.ts","sourceRoot":"","sources":["../src/layout-prompt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"layout-prompt.d.ts","sourceRoot":"","sources":["../src/layout-prompt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,6zIAwDhC,CAAC;AAEF,wBAAgB,sBAAsB;;;;EAMrC"}
|
package/dist/layout-prompt.js
CHANGED
|
@@ -5,12 +5,15 @@ Always run \`ls\` before constructing a path. PR 0 standardizes human-readable l
|
|
|
5
5
|
## Tree
|
|
6
6
|
|
|
7
7
|
\`/linear/LAYOUT.md\` is this guide.
|
|
8
|
-
\`/linear/issues/\`, \`/linear/comments/\`, \`/linear/users/\`, \`/linear/teams/\`, \`/linear/projects/\`, \`/linear/cycles/\`, \`/linear/milestones/\`, and \`/linear/roadmaps/\` each own their canonical JSON records plus a sibling \`_index.json\`.
|
|
8
|
+
\`/linear/issues/\`, \`/linear/comments/\`, \`/linear/users/\`, \`/linear/teams/\`, \`/linear/projects/\`, \`/linear/states/\`, \`/linear/cycles/\`, \`/linear/milestones/\`, and \`/linear/roadmaps/\` each own their canonical JSON records plus a sibling \`_index.json\`.
|
|
9
9
|
\`/linear/comments/<name>__<id>/meta.json\` is the canonical comment record (a directory record, so per-comment children such as reactions or threaded replies can nest under \`comments/<name>__<id>/\` without a file/directory collision).
|
|
10
|
+
\`/linear/projects/<uuid>/meta.json\` is the canonical project record. The legacy flat \`/linear/projects/<uuid>.json\` path is not written by current mirrors.
|
|
10
11
|
|
|
11
12
|
Issue lookups: \`/linear/issues/by-uuid/<uuid>.json\` is the stable anchor (always emitted, keyed on the Linear UUID). \`/linear/issues/by-id/<TEAM-123>.json\` is the human-readable lookup keyed on the Linear identifier (only emitted when the issue has one). \`/linear/issues/by-title/<slug>.json\`, \`/linear/issues/by-state/<state>/<TEAM-123>.json\`, \`/linear/issues/by-assignee/<user-id>/<TEAM-123>.json\`, \`/linear/issues/by-creator/<user-id>/<TEAM-123>.json\`, \`/linear/issues/by-priority/<priority>/<TEAM-123>.json\`, and \`/linear/issues/by-edited/YYYY-MM-DD/<issue-uuid>.json\` are additional lookups. The edited-date bucket is formatted as \`YYYY-MM-DD\` and uses the first available timestamp in this order: \`updatedAt\`, \`updated_at\`, \`completedAt\`, \`canceledAt\`, \`createdAt\`, then \`created_at\`.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Project lookups: \`/linear/projects/by-id/<uuid>.json\` is the stable project id lookup, \`/linear/projects/by-name/<slug>.json\` resolves a project by name, \`/linear/projects/by-state/<backlog|planned|started|paused|completed|canceled>/<uuid>.json\` groups by Linear project state, and \`/linear/projects/by-team/<team-uuid>/<project-uuid>.json\` is emitted once per team on multi-team projects.
|
|
15
|
+
|
|
16
|
+
Writable resources advertise sibling schemas and create examples at \`discovery/linear/issues/.schema.json\`, \`discovery/linear/issues/.create.example.json\`, \`discovery/linear/issues/{issueId}/comments/.schema.json\`, \`discovery/linear/issues/{issueId}/comments/.create.example.json\`, \`discovery/linear/projects/.schema.json\`, \`discovery/linear/projects/.create.example.json\`, \`discovery/linear/projects/{projectId}/meta.json/.schema.json\`, \`discovery/linear/projects/{projectId}/meta.json/.create.example.json\`, \`discovery/linear/projects/{projectId}/add-issues.json/.schema.json\`, and \`discovery/linear/projects/{projectId}/add-issues.json/.create.example.json\`.
|
|
14
17
|
|
|
15
18
|
## Indexes
|
|
16
19
|
|
|
@@ -20,7 +23,7 @@ Writable resources advertise sibling schemas and create examples at \`discovery/
|
|
|
20
23
|
{ "id": "<id>", "title": "<human-readable>", "updated": "<iso8601>", "identifier": "<TEAM-123>", "state": "<state name>" }
|
|
21
24
|
\`\`\`
|
|
22
25
|
|
|
23
|
-
\`/linear/comments/_index.json\`, \`/linear/users/_index.json\`, \`/linear/teams/_index.json\`, \`/linear/projects/_index.json\`, \`/linear/cycles/_index.json\`, \`/linear/milestones/_index.json\`, and \`/linear/roadmaps/_index.json\` use:
|
|
26
|
+
\`/linear/comments/_index.json\`, \`/linear/users/_index.json\`, \`/linear/teams/_index.json\`, \`/linear/projects/_index.json\`, \`/linear/states/_index.json\`, \`/linear/cycles/_index.json\`, \`/linear/milestones/_index.json\`, and \`/linear/roadmaps/_index.json\` use:
|
|
24
27
|
|
|
25
28
|
\`\`\`json
|
|
26
29
|
{ "id": "<id>", "title": "<human-readable>", "updated": "<iso8601>" }
|
|
@@ -40,7 +43,14 @@ ls /linear/issues/by-assignee
|
|
|
40
43
|
ls /linear/issues/by-priority
|
|
41
44
|
ls /linear/issues/by-edited/2026-05-12
|
|
42
45
|
jq '.identifier' /linear/issues/by-edited/2026-05-12/11111111-1111-1111-1111-111111111111.json
|
|
46
|
+
jq '.[0]' /linear/projects/_index.json
|
|
47
|
+
ls /linear/projects/by-name
|
|
48
|
+
ls /linear/projects/by-state/started
|
|
49
|
+
jq '.payload.id' /linear/projects/by-team/22222222-2222-2222-2222-222222222222/11111111-1111-1111-1111-111111111111.json
|
|
50
|
+
jq '.[0]' /linear/states/_index.json
|
|
43
51
|
jq '.required' discovery/linear/issues/.schema.json
|
|
52
|
+
cat discovery/linear/projects/.create.example.json
|
|
53
|
+
cat discovery/linear/projects/{projectId}/add-issues.json/.create.example.json
|
|
44
54
|
ls discovery/linear/issues/{issueId}/comments
|
|
45
55
|
grep -R "ENG-" /linear/comments
|
|
46
56
|
\`\`\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-prompt.js","sourceRoot":"","sources":["../src/layout-prompt.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG
|
|
1
|
+
{"version":3,"file":"layout-prompt.js","sourceRoot":"","sources":["../src/layout-prompt.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDnC,CAAC;AAEF,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,8BAAuC;QACpD,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,oBAAoB,IAAI;KAClG,CAAC;AACJ,CAAC"}
|
package/dist/layout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAEpG,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAEpG,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,eAAO,MAAM,cAAc,EAAE,0BA6C3B,CAAC"}
|
package/dist/layout.js
CHANGED
|
@@ -3,8 +3,9 @@ export const layoutManifest = () => ({
|
|
|
3
3
|
filenameConvention: '<identifier>__<uuid>.json',
|
|
4
4
|
// Top-level aliasSegments is the union of every resource's alias segments
|
|
5
5
|
// so consumers that inspect only the manifest root can discover all
|
|
6
|
-
// lookup keys. `by-name` belongs here because `linear/teams`
|
|
7
|
-
|
|
6
|
+
// lookup keys. `by-name` belongs here because `linear/teams` and
|
|
7
|
+
// `linear/projects` expose it.
|
|
8
|
+
aliasSegments: ['by-assignee', 'by-creator', 'by-edited', 'by-id', 'by-name', 'by-priority', 'by-title', 'by-state', 'by-team', 'by-uuid'],
|
|
8
9
|
resources: [
|
|
9
10
|
{
|
|
10
11
|
path: 'linear/issues',
|
|
@@ -20,7 +21,18 @@ export const layoutManifest = () => ({
|
|
|
20
21
|
path: 'linear/projects',
|
|
21
22
|
title: 'Projects',
|
|
22
23
|
materialization: 'eager',
|
|
23
|
-
aliasSegments: ['by-id', 'by-
|
|
24
|
+
aliasSegments: ['by-id', 'by-name', 'by-state', 'by-team'],
|
|
25
|
+
writebackResources: [
|
|
26
|
+
{ path: 'linear/projects', schemaId: 'linear/project' },
|
|
27
|
+
{ path: 'linear/projects/*/meta.json', schemaId: 'linear/project-update' },
|
|
28
|
+
{ path: 'linear/projects/*/add-issues.json', schemaId: 'linear/project-issue-assignment' },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
path: 'linear/states',
|
|
33
|
+
title: 'Workflow States',
|
|
34
|
+
materialization: 'eager',
|
|
35
|
+
aliasSegments: [],
|
|
24
36
|
writebackResources: [],
|
|
25
37
|
},
|
|
26
38
|
{
|
package/dist/layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,cAAc,GAA+B,GAAG,EAAE,CAAC,CAAC;IAC/D,QAAQ,EAAE,QAAQ;IAClB,kBAAkB,EAAE,2BAA2B;IAC/C,0EAA0E;IAC1E,oEAAoE;IACpE,
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,cAAc,GAA+B,GAAG,EAAE,CAAC,CAAC;IAC/D,QAAQ,EAAE,QAAQ;IAClB,kBAAkB,EAAE,2BAA2B;IAC/C,0EAA0E;IAC1E,oEAAoE;IACpE,iEAAiE;IACjE,+BAA+B;IAC/B,aAAa,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;IAC1I,SAAS,EAAE;QACT;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,CAAC;YACpH,kBAAkB,EAAE;gBAClB,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE;gBACnD,EAAE,IAAI,EAAE,wBAAwB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;aAC/D;SACF;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,UAAU;YACjB,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC;YAC1D,kBAAkB,EAAE;gBAClB,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;gBACvD,EAAE,IAAI,EAAE,6BAA6B,EAAE,QAAQ,EAAE,uBAAuB,EAAE;gBAC1E,EAAE,IAAI,EAAE,mCAAmC,EAAE,QAAQ,EAAE,iCAAiC,EAAE;aAC3F;SACF;QACD;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,iBAAiB;YACxB,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,EAAE;YACjB,kBAAkB,EAAE,EAAE;SACvB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,OAAO;YACd,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;YACnC,kBAAkB,EAAE,EAAE;SACvB;KACF;CACF,CAAC,CAAC"}
|
package/dist/layout.test.js
CHANGED
|
@@ -9,6 +9,7 @@ const CANONICAL_ALIAS_SEGMENTS = new Set([
|
|
|
9
9
|
'by-name',
|
|
10
10
|
'by-priority',
|
|
11
11
|
'by-state',
|
|
12
|
+
'by-team',
|
|
12
13
|
'by-title',
|
|
13
14
|
'by-uuid',
|
|
14
15
|
]);
|
|
@@ -24,9 +25,11 @@ test('layoutManifest exposes Linear resources with canonical aliases and writeba
|
|
|
24
25
|
'by-priority',
|
|
25
26
|
'by-title',
|
|
26
27
|
'by-state',
|
|
28
|
+
'by-team',
|
|
27
29
|
'by-uuid',
|
|
28
30
|
]);
|
|
29
31
|
assert.ok(manifest.resources.length > 0);
|
|
32
|
+
assert.ok(manifest.resources.some((resource) => resource.path === 'linear/states'));
|
|
30
33
|
for (const resource of manifest.resources) {
|
|
31
34
|
assert.ok(resource.path.startsWith('linear/'));
|
|
32
35
|
assert.doesNotMatch(resource.path, /^\//u);
|
package/dist/layout.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.test.js","sourceRoot":"","sources":["../src/layout.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IACvC,aAAa;IACb,YAAY;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT,aAAa;IACb,UAAU;IACV,UAAU;IACV,SAAS;CACV,CAAC,CAAC;AAEH,IAAI,CAAC,8FAA8F,EAAE,GAAG,EAAE;IACxG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE;QACvC,aAAa;QACb,YAAY;QACZ,WAAW;QACX,OAAO;QACP,SAAS;QACT,aAAa;QACb,UAAU;QACV,UAAU;QACV,SAAS;KACV,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"layout.test.js","sourceRoot":"","sources":["../src/layout.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IACvC,aAAa;IACb,YAAY;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT,aAAa;IACb,UAAU;IACV,SAAS;IACT,UAAU;IACV,SAAS;CACV,CAAC,CAAC;AAEH,IAAI,CAAC,8FAA8F,EAAE,GAAG,EAAE;IACxG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE;QACvC,aAAa;QACb,YAAY;QACZ,WAAW;QACX,OAAO;QACP,SAAS;QACT,aAAa;QACb,UAAU;QACV,UAAU;QACV,SAAS;QACT,SAAS;KACV,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC;IAEpF,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3C,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YACpD,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0FAA0F,EAAE,GAAG,EAAE;IACpG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACjD,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3C,MAAM,CAAC,EAAE,CACP,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EACnB,mCAAmC,KAAK,yBAAyB,QAAQ,CAAC,IAAI,EAAE,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear-adapter.d.ts","sourceRoot":"","sources":["../src/linear-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQzD,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"linear-adapter.d.ts","sourceRoot":"","sources":["../src/linear-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/linear-adapter.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cleanupStaleAliases, readAliasKeyFromContent, upsertIndexAtomic, } from '@relayfile/adapter-core';
|
|
2
|
-
import { computeLinearPath, LINEAR_PATH_ROOT, linearAgentWebhookEventPath, linearByIdAliasPath, linearByTitleAliasPath, linearCyclePath, linearIssueByStatePath, linearIssuePath, linearMilestonePath, linearProjectPath, linearRoadmapPath, linearTeamPath, linearUserPath, normalizeLinearObjectType, } from './path-mapper.js';
|
|
2
|
+
import { computeLinearPath, LINEAR_PATH_ROOT, linearAgentWebhookEventPath, linearByIdAliasPath, linearByNameAliasPath, linearByTitleAliasPath, linearCyclePath, linearIssueByStatePath, linearIssuePath, linearMilestonePath, linearProjectByStatePath, linearProjectByTeamPath, linearProjectPath, linearRoadmapPath, linearTeamPath, linearUserPath, normalizeLinearObjectType, } from './path-mapper.js';
|
|
3
3
|
import { buildLinearIndexFile } from './index-emitter.js';
|
|
4
4
|
import { linearLayoutPromptFile } from './layout-prompt.js';
|
|
5
|
-
import { getLinearCommentHumanReadable, getLinearIssueHumanReadable, linearCommentIndexRow, linearCycleIndexRow, linearIssueIndexRow, linearMilestoneIndexRow, linearProjectIndexRow, linearRoadmapIndexRow, linearTeamIndexRow, linearUserIndexRow, } from './queries.js';
|
|
5
|
+
import { getLinearCommentHumanReadable, getLinearIssueHumanReadable, linearCommentIndexRow, linearCycleIndexRow, linearIssueIndexRow, linearMilestoneIndexRow, linearProjectIndexRow, linearRoadmapIndexRow, linearStateIndexRow, linearTeamIndexRow, linearUserIndexRow, } from './queries.js';
|
|
6
6
|
import { LINEAR_AGENT_WEBHOOK_EVENTS, LINEAR_WEBHOOK_OBJECT_TYPES } from './types.js';
|
|
7
7
|
import { normalizeLinearWebhook } from './webhook-normalizer.js';
|
|
8
8
|
export class IntegrationAdapter {
|
|
@@ -461,7 +461,9 @@ function applyIssueSemantics(properties, relations, payload) {
|
|
|
461
461
|
relations.add(linearProjectPath(issue.project.id));
|
|
462
462
|
addStringProperty(properties, 'linear.project_id', issue.project.id);
|
|
463
463
|
addStringProperty(properties, 'linear.project_name', issue.project.name);
|
|
464
|
+
addFirstStringProperty(properties, 'linear.project_slug', issue.project.slug, issue.project.slugId);
|
|
464
465
|
addStringProperty(properties, 'linear.project_state', issue.project.state);
|
|
466
|
+
addFirstStringProperty(properties, 'linear.project_lead_id', issue.project.lead?.id, issue.project.leadId);
|
|
465
467
|
addStringProperty(properties, 'linear.project_url', issue.project.url);
|
|
466
468
|
}
|
|
467
469
|
const projectId = asString(issue.project_id);
|
|
@@ -564,12 +566,17 @@ function applyProjectSemantics(properties, relations, payload) {
|
|
|
564
566
|
const project = payload;
|
|
565
567
|
addStringProperty(properties, 'linear.name', project.name);
|
|
566
568
|
addStringProperty(properties, 'linear.state', project.state);
|
|
569
|
+
addFirstStringProperty(properties, 'linear.slug', project.slug, project.slugId);
|
|
567
570
|
addFirstStringProperty(properties, 'linear.description', project.description);
|
|
571
|
+
addFirstStringProperty(properties, 'linear.start_date', project.startDate, project.start_date);
|
|
568
572
|
addFirstStringProperty(properties, 'linear.target_date', project.targetDate, project.target_date);
|
|
569
573
|
addFirstStringProperty(properties, 'linear.started_at', project.startedAt, project.started_at);
|
|
570
574
|
addFirstStringProperty(properties, 'linear.completed_at', project.completedAt, project.completed_at);
|
|
571
575
|
addFirstStringProperty(properties, 'linear.created_at', project.createdAt, project.created_at);
|
|
572
576
|
addFirstStringProperty(properties, 'linear.updated_at', project.updatedAt, project.updated_at);
|
|
577
|
+
addFirstStringProperty(properties, 'linear.lead_id', project.lead?.id, project.leadId, project.lead_id);
|
|
578
|
+
addFirstStringProperty(properties, 'linear.color', project.color);
|
|
579
|
+
addFirstStringProperty(properties, 'linear.icon', project.icon);
|
|
573
580
|
const progress = asNumber(project.progress);
|
|
574
581
|
if (progress !== undefined) {
|
|
575
582
|
properties['linear.progress'] = String(progress);
|
|
@@ -586,6 +593,12 @@ function applyProjectSemantics(properties, relations, payload) {
|
|
|
586
593
|
}
|
|
587
594
|
}
|
|
588
595
|
}
|
|
596
|
+
function readProjectTeamIdsFromPayload(payload) {
|
|
597
|
+
return uniqueStrings([
|
|
598
|
+
...asStringArray(payload.team_ids),
|
|
599
|
+
...asLinearReferenceIds(payload.teams),
|
|
600
|
+
]);
|
|
601
|
+
}
|
|
589
602
|
function buildLinearIssueReferencePath(issue) {
|
|
590
603
|
return linearIssuePath(issue.id, getLinearIssueHumanReadable(issue));
|
|
591
604
|
}
|
|
@@ -747,10 +760,14 @@ function buildIndexRow(bucket, event) {
|
|
|
747
760
|
return linearProjectIndexRow(payload);
|
|
748
761
|
case 'roadmaps':
|
|
749
762
|
return linearRoadmapIndexRow(payload);
|
|
763
|
+
case 'states':
|
|
764
|
+
return linearStateIndexRow(payload);
|
|
750
765
|
case 'teams':
|
|
751
766
|
return linearTeamIndexRow(payload);
|
|
752
767
|
case 'users':
|
|
753
768
|
return linearUserIndexRow(payload);
|
|
769
|
+
default:
|
|
770
|
+
throw new Error(`Unsupported Linear index bucket: ${bucket}`);
|
|
754
771
|
}
|
|
755
772
|
}
|
|
756
773
|
function buildIndexFileForBucket(bucket, rows) {
|
|
@@ -767,10 +784,14 @@ function buildIndexFileForBucket(bucket, rows) {
|
|
|
767
784
|
return buildLinearIndexFile('projects', rows);
|
|
768
785
|
case 'roadmaps':
|
|
769
786
|
return buildLinearIndexFile('roadmaps', rows);
|
|
787
|
+
case 'states':
|
|
788
|
+
return buildLinearIndexFile('states', rows);
|
|
770
789
|
case 'teams':
|
|
771
790
|
return buildLinearIndexFile('teams', rows);
|
|
772
791
|
case 'users':
|
|
773
792
|
return buildLinearIndexFile('users', rows);
|
|
793
|
+
default:
|
|
794
|
+
throw new Error(`Unsupported Linear index bucket: ${bucket}`);
|
|
774
795
|
}
|
|
775
796
|
}
|
|
776
797
|
function buildIndexPathForBucket(bucket) {
|
|
@@ -955,21 +976,34 @@ async function writeLinearAliases(client, workspaceId, event, canonicalPath, con
|
|
|
955
976
|
// Snapshot the previous record version before the by-id alias is
|
|
956
977
|
// overwritten — it carries the prior title/name for stale alias cleanup.
|
|
957
978
|
const previousContent = await readLinearFile(client, byIdAliasPath, workspaceId);
|
|
958
|
-
await writeLinearIndex(client, workspaceId, scope);
|
|
979
|
+
await writeLinearIndex(client, workspaceId, scope, { objectType: normalizedType });
|
|
959
980
|
await writeLinearFile(client, workspaceId, byIdAliasPath, content, semantics);
|
|
960
981
|
let writtenAliasPath;
|
|
961
982
|
if (title) {
|
|
962
|
-
const baseAliasPath =
|
|
983
|
+
const baseAliasPath = normalizedType === 'issue'
|
|
984
|
+
? linearByTitleAliasPath(scope, title, event.objectId)
|
|
985
|
+
: linearByNameAliasPath(scope, title, event.objectId);
|
|
963
986
|
const existingBaseContent = await readLinearFile(client, baseAliasPath, workspaceId);
|
|
964
987
|
// A base alias holding this record's previous bytes is ours — overwrite
|
|
965
988
|
// it in place instead of forking to the collision variant.
|
|
966
989
|
const ownsBaseAlias = existingBaseContent !== undefined && existingBaseContent === previousContent;
|
|
967
990
|
const aliasPath = existingBaseContent !== undefined && existingBaseContent !== content && !ownsBaseAlias
|
|
968
|
-
?
|
|
991
|
+
? normalizedType === 'issue'
|
|
992
|
+
? linearByTitleAliasPath(scope, title, event.objectId, true)
|
|
993
|
+
: linearByNameAliasPath(scope, title, event.objectId, true)
|
|
969
994
|
: baseAliasPath;
|
|
970
995
|
await writeLinearFile(client, workspaceId, aliasPath, content, semantics);
|
|
971
996
|
writtenAliasPath = aliasPath;
|
|
972
997
|
}
|
|
998
|
+
if (normalizedType === 'project') {
|
|
999
|
+
const state = asString(event.payload.state);
|
|
1000
|
+
if (state) {
|
|
1001
|
+
await writeLinearFile(client, workspaceId, linearProjectByStatePath(state, event.objectId), content, semantics);
|
|
1002
|
+
}
|
|
1003
|
+
for (const teamId of readProjectTeamIdsFromPayload(event.payload)) {
|
|
1004
|
+
await writeLinearFile(client, workspaceId, linearProjectByTeamPath(teamId, event.objectId), content, semantics);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
973
1007
|
// Stale alias lifecycle (issue #106): delete the previous by-title alias
|
|
974
1008
|
// when the record's title/name changed. Only the stale alias file is
|
|
975
1009
|
// removed — the canonical record file is never touched.
|
|
@@ -982,7 +1016,7 @@ async function writeLinearAliases(client, workspaceId, event, canonicalPath, con
|
|
|
982
1016
|
});
|
|
983
1017
|
}
|
|
984
1018
|
/**
|
|
985
|
-
* Removes the stale
|
|
1019
|
+
* Removes the stale human-readable alias left behind when an issue title or
|
|
986
1020
|
* project name changes between ingests (issue #106).
|
|
987
1021
|
*
|
|
988
1022
|
* Prior state comes from the mirror itself: the title-independent `by-id`
|
|
@@ -1016,7 +1050,11 @@ async function cleanupStaleLinearTitleAliases(client, workspaceId, options) {
|
|
|
1016
1050
|
}
|
|
1017
1051
|
const candidatePaths = [];
|
|
1018
1052
|
try {
|
|
1019
|
-
candidatePaths.push(
|
|
1053
|
+
candidatePaths.push(objectType === 'issue'
|
|
1054
|
+
? linearByTitleAliasPath(scope, previousTitle, objectId)
|
|
1055
|
+
: linearByNameAliasPath(scope, previousTitle, objectId), objectType === 'issue'
|
|
1056
|
+
? linearByTitleAliasPath(scope, previousTitle, objectId, true)
|
|
1057
|
+
: linearByNameAliasPath(scope, previousTitle, objectId, true));
|
|
1020
1058
|
}
|
|
1021
1059
|
catch {
|
|
1022
1060
|
// Previous title slugs to an empty string — no alias was emitted for it.
|
|
@@ -1034,10 +1072,21 @@ async function cleanupStaleLinearTitleAliases(client, workspaceId, options) {
|
|
|
1034
1072
|
async function writeLinearIndex(client, workspaceId, scope, options) {
|
|
1035
1073
|
const indexPath = `${scope}/_index.json`;
|
|
1036
1074
|
const vfs = linearClientToVfs(client, workspaceId);
|
|
1037
|
-
await upsertIndexAtomic(vfs, indexPath, parseLinearIndexRows, (rows) => mergeLinearIndexRowsList(rows,
|
|
1075
|
+
await upsertIndexAtomic(vfs, indexPath, parseLinearIndexRows, (rows) => mergeLinearIndexRowsList(rows, indexAliasRows(options?.objectType)), (rows) => stableJson({ rows }), options);
|
|
1076
|
+
}
|
|
1077
|
+
function indexAliasRows(objectType) {
|
|
1078
|
+
if (objectType === 'project') {
|
|
1079
|
+
return [
|
|
1080
|
+
{ title: 'by-id', file: 'by-id/' },
|
|
1081
|
+
{ title: 'by-name', file: 'by-name/' },
|
|
1082
|
+
{ title: 'by-state', file: 'by-state/' },
|
|
1083
|
+
{ title: 'by-team', file: 'by-team/' },
|
|
1084
|
+
];
|
|
1085
|
+
}
|
|
1086
|
+
return [
|
|
1038
1087
|
{ title: 'by-id', file: 'by-id/' },
|
|
1039
1088
|
{ title: 'by-title', file: 'by-title/' },
|
|
1040
|
-
]
|
|
1089
|
+
];
|
|
1041
1090
|
}
|
|
1042
1091
|
/**
|
|
1043
1092
|
* Wrap the linear `RelayFileClientLike` (single-input WriteFileInput shape)
|