linmux 0.1.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 (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -0
  3. package/bin/run.js +4 -0
  4. package/dist/commands/comment/create.js +94 -0
  5. package/dist/commands/comment/delete.js +74 -0
  6. package/dist/commands/comment/list.js +84 -0
  7. package/dist/commands/comment/update.js +80 -0
  8. package/dist/commands/cycle/current.js +78 -0
  9. package/dist/commands/cycle/list.js +84 -0
  10. package/dist/commands/cycle/move.js +91 -0
  11. package/dist/commands/describe.js +65 -0
  12. package/dist/commands/graphql/index.js +92 -0
  13. package/dist/commands/install-skill.js +54 -0
  14. package/dist/commands/issue/archive.js +75 -0
  15. package/dist/commands/issue/create.js +115 -0
  16. package/dist/commands/issue/get.js +84 -0
  17. package/dist/commands/issue/list.js +93 -0
  18. package/dist/commands/issue/purge.js +81 -0
  19. package/dist/commands/issue/search.js +109 -0
  20. package/dist/commands/issue/transition.js +91 -0
  21. package/dist/commands/issue/trash.js +75 -0
  22. package/dist/commands/issue/update.js +126 -0
  23. package/dist/commands/label/create.js +91 -0
  24. package/dist/commands/label/list.js +76 -0
  25. package/dist/commands/list-tools.js +47 -0
  26. package/dist/commands/me.js +71 -0
  27. package/dist/commands/project/create.js +101 -0
  28. package/dist/commands/project/get.js +83 -0
  29. package/dist/commands/project/list.js +75 -0
  30. package/dist/commands/project/update-status.js +99 -0
  31. package/dist/commands/project/update.js +99 -0
  32. package/dist/commands/raw/batch.js +85 -0
  33. package/dist/commands/raw/index.js +72 -0
  34. package/dist/commands/schema.js +69 -0
  35. package/dist/commands/state/list.js +77 -0
  36. package/dist/commands/team/get.js +73 -0
  37. package/dist/commands/team/list.js +73 -0
  38. package/dist/commands/whoami.js +71 -0
  39. package/dist/commands/workspace/add.js +97 -0
  40. package/dist/commands/workspace/list.js +47 -0
  41. package/dist/commands/workspace/remove.js +63 -0
  42. package/dist/commands/workspace/replace-token.js +89 -0
  43. package/dist/commands/workspace/use.js +54 -0
  44. package/dist/core/client/factory.js +28 -0
  45. package/dist/core/client/index.js +2 -0
  46. package/dist/core/config/index.js +4 -0
  47. package/dist/core/config/paths.js +30 -0
  48. package/dist/core/config/schema.js +36 -0
  49. package/dist/core/config/store.js +149 -0
  50. package/dist/core/errors/error.js +142 -0
  51. package/dist/core/errors/exit-codes.js +70 -0
  52. package/dist/core/output/envelope.js +53 -0
  53. package/dist/core/output/format.js +42 -0
  54. package/dist/core/output/index.js +3 -0
  55. package/dist/core/pagination/flags.js +29 -0
  56. package/dist/core/pagination/index.js +2 -0
  57. package/dist/core/projection/presets.js +116 -0
  58. package/dist/core/projection/project.js +282 -0
  59. package/dist/core/redact/redact.js +45 -0
  60. package/dist/core/resolvers/cycle.js +60 -0
  61. package/dist/core/resolvers/index.js +7 -0
  62. package/dist/core/resolvers/label.js +54 -0
  63. package/dist/core/resolvers/project-status.js +42 -0
  64. package/dist/core/resolvers/project.js +43 -0
  65. package/dist/core/resolvers/state.js +46 -0
  66. package/dist/core/resolvers/team.js +50 -0
  67. package/dist/core/transport/fetch-interceptor.js +109 -0
  68. package/dist/core/transport/index.js +3 -0
  69. package/dist/core/transport/rate-limit.js +167 -0
  70. package/dist/core/workspace/resolver.js +70 -0
  71. package/dist/core/workspace/write-guard.js +43 -0
  72. package/dist/generated/graphql.js +89428 -0
  73. package/dist/generated/operations.js +3013 -0
  74. package/dist/lib/comment-create-runtime.js +96 -0
  75. package/dist/lib/comment-delete-runtime.js +46 -0
  76. package/dist/lib/comment-list-runtime.js +182 -0
  77. package/dist/lib/comment-update-runtime.js +93 -0
  78. package/dist/lib/cycle-current-runtime.js +90 -0
  79. package/dist/lib/cycle-list-runtime.js +151 -0
  80. package/dist/lib/cycle-move-runtime.js +142 -0
  81. package/dist/lib/describe-runtime.js +180 -0
  82. package/dist/lib/filter-heuristics.js +59 -0
  83. package/dist/lib/graphql-runtime.js +202 -0
  84. package/dist/lib/include-fragments.js +73 -0
  85. package/dist/lib/install-skill-runtime.js +228 -0
  86. package/dist/lib/introspection-registry.js +488 -0
  87. package/dist/lib/issue-archive-runtime.js +89 -0
  88. package/dist/lib/issue-create-runtime.js +175 -0
  89. package/dist/lib/issue-get-runtime.js +153 -0
  90. package/dist/lib/issue-list-runtime.js +164 -0
  91. package/dist/lib/issue-purge-runtime.js +89 -0
  92. package/dist/lib/issue-search-runtime.js +114 -0
  93. package/dist/lib/issue-transition-runtime.js +131 -0
  94. package/dist/lib/issue-trash-runtime.js +84 -0
  95. package/dist/lib/issue-update-runtime.js +164 -0
  96. package/dist/lib/label-create-runtime.js +113 -0
  97. package/dist/lib/label-list-runtime.js +97 -0
  98. package/dist/lib/levenshtein.js +42 -0
  99. package/dist/lib/list-tools-runtime.js +38 -0
  100. package/dist/lib/me-runtime.js +55 -0
  101. package/dist/lib/project-create-runtime.js +103 -0
  102. package/dist/lib/project-get-runtime.js +134 -0
  103. package/dist/lib/project-list-runtime.js +84 -0
  104. package/dist/lib/project-update-runtime.js +110 -0
  105. package/dist/lib/project-update-status-runtime.js +91 -0
  106. package/dist/lib/raw-batch-runtime.js +229 -0
  107. package/dist/lib/raw-runtime.js +171 -0
  108. package/dist/lib/schema-loader.js +41 -0
  109. package/dist/lib/schema-runtime.js +65 -0
  110. package/dist/lib/state-list-runtime.js +93 -0
  111. package/dist/lib/team-get-runtime.js +55 -0
  112. package/dist/lib/team-list-runtime.js +52 -0
  113. package/dist/lib/workspace-runtime.js +112 -0
  114. package/dist/operations/_registry.zod.js +5337 -0
  115. package/oclif.manifest.json +3631 -0
  116. package/package.json +99 -0
  117. package/schema.graphql +30772 -0
  118. package/skills/linmux/SKILL.md +186 -0
@@ -0,0 +1,85 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { runRawBatch } from "../../lib/raw-batch-runtime.js";
3
+ import { Command, Flags } from "@oclif/core";
4
+ //#region src/commands/raw/batch.ts
5
+ /**
6
+ * `linmux raw batch --plan=@file.json` — Phase 3 PLAN 03-05, RAW-05.
7
+ *
8
+ * Safety-gated batch dispatcher. Defaults to --dry-run; requires --yes to execute.
9
+ * Implementation lives in `src/lib/raw-batch-runtime.ts` (two-export pattern S1).
10
+ *
11
+ * This file exports BOTH:
12
+ * - Named `runRawBatch` re-export (for tests + future programmatic use)
13
+ * - Default `RawBatchCommand` oclif class
14
+ *
15
+ * Gate ordering (enforced in runtime):
16
+ * Plan validation → WSP-06 (if mutations) → --allow-mutations → dry-run/yes intent
17
+ *
18
+ * oclif resolves `src/commands/raw/batch.ts` → `linmux raw batch` automatically
19
+ * via topic-tree convention.
20
+ */
21
+ var RawBatchCommand = class RawBatchCommand extends Command {
22
+ static description = "Execute a batch of registry operations from a JSON plan file. Default dry-run; --yes required to execute.";
23
+ static examples = [
24
+ "<%= config.bin %> raw batch --plan=@./plan.json",
25
+ "<%= config.bin %> raw batch --plan=@./plan.json --workspace acme --allow-mutations --yes",
26
+ "<%= config.bin %> raw batch --plan=@./plan.json --no-dry-run --yes --workspace acme --allow-mutations"
27
+ ];
28
+ static enableJsonFlag = true;
29
+ static flags = {
30
+ ...BASE_FLAGS,
31
+ workspace: Flags.string({ description: "Workspace name override (precedence over LINEAR_WORKSPACE env / active default)" }),
32
+ "allow-active-workspace-write": Flags.boolean({
33
+ default: false,
34
+ description: "Permit mutations against the active workspace without an explicit --workspace selector (WSP-06 opt-in)"
35
+ }),
36
+ "allow-mutations": Flags.boolean({
37
+ default: false,
38
+ description: "Required for plans containing mutation operations — explicit safety gate"
39
+ }),
40
+ plan: Flags.string({
41
+ required: true,
42
+ description: "Plan file path as @file.json (e.g. --plan=@./plan.json)"
43
+ }),
44
+ "dry-run": Flags.boolean({
45
+ default: true,
46
+ allowNo: true,
47
+ description: "Print planned operations without executing (default true). Pass --no-dry-run --yes to execute."
48
+ }),
49
+ yes: Flags.boolean({
50
+ default: false,
51
+ description: "Confirm execution. Required when --no-dry-run is passed."
52
+ })
53
+ };
54
+ async run() {
55
+ const { flags } = await this.parse(RawBatchCommand);
56
+ const batchFlags = {
57
+ plan: flags.plan,
58
+ pretty: flags.pretty,
59
+ "dry-run": flags["dry-run"],
60
+ yes: flags.yes,
61
+ "allow-mutations": flags["allow-mutations"],
62
+ "allow-active-workspace-write": flags["allow-active-workspace-write"]
63
+ };
64
+ if (flags.workspace !== void 0) batchFlags.workspace = flags.workspace;
65
+ const runArgs = {
66
+ commandPath: "raw batch",
67
+ pretty: flags.pretty ?? false,
68
+ handler: (retryOpts) => runRawBatch({
69
+ flags: batchFlags,
70
+ env: process.env,
71
+ retryOptsOverride: retryOpts
72
+ })
73
+ };
74
+ if (flags.quiet !== void 0) runArgs.quiet = flags.quiet;
75
+ if (flags.noMeta !== void 0) runArgs.noMeta = flags.noMeta;
76
+ if (flags.retry !== void 0) runArgs.retry = flags.retry;
77
+ const out = await runCommand(runArgs);
78
+ if (!flags.json) process.stdout.write(out.stdout);
79
+ if (out.stderr) process.stderr.write(out.stderr);
80
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
81
+ return JSON.parse(out.stdout);
82
+ }
83
+ };
84
+ //#endregion
85
+ export { RawBatchCommand as default, runRawBatch };
@@ -0,0 +1,72 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { runRaw } from "../../lib/raw-runtime.js";
3
+ import { Args, Command, Flags } from "@oclif/core";
4
+ //#region src/commands/raw/index.ts
5
+ /**
6
+ * `linmux raw <Operation>` — Phase 3 PLAN 03-02.
7
+ *
8
+ * Dispatches any operation in the generated GraphQL registry.
9
+ * Implementation lives in `src/lib/raw-runtime.ts` (two-export pattern S1 —
10
+ * analog: `src/commands/issue/transition.ts:19-95`).
11
+ *
12
+ * This file exports BOTH:
13
+ * - Named `runRaw` re-export (for tests + future programmatic use)
14
+ * - Default `RawCommand` oclif class
15
+ *
16
+ * Gate ordering (enforced in runtime):
17
+ * WSP-06 (workspace selector) BEFORE --allow-mutations BEFORE dispatch.
18
+ */
19
+ var RawCommand = class RawCommand extends Command {
20
+ static description = "Dispatch any operation in the generated GraphQL registry (501 ops).";
21
+ static examples = [
22
+ "<%= config.bin %> raw Issues --vars '{\"first\": 10}'",
23
+ "<%= config.bin %> raw IssueCreate --workspace acme --allow-mutations --vars '{\"input\": {\"title\": \"x\", \"teamId\": \"...\"}}'",
24
+ "<%= config.bin %> raw Issues --vars @vars.json"
25
+ ];
26
+ static enableJsonFlag = true;
27
+ static args = { operation: Args.string({
28
+ required: true,
29
+ description: "PascalCase operation name (e.g. Issues, IssueCreate)"
30
+ }) };
31
+ static flags = {
32
+ ...BASE_FLAGS,
33
+ workspace: Flags.string({ description: "Workspace name override (precedence over LINEAR_WORKSPACE env / active default)" }),
34
+ "allow-active-workspace-write": Flags.boolean({
35
+ default: false,
36
+ description: "Permit mutations against the active workspace without an explicit --workspace selector (WSP-06 opt-in)"
37
+ }),
38
+ "allow-mutations": Flags.boolean({
39
+ default: false,
40
+ description: "Required for mutation operations — explicit safety gate"
41
+ }),
42
+ vars: Flags.string({ description: "Variables as inline JSON or @file.json path (file takes precedence)" })
43
+ };
44
+ async run() {
45
+ const { args, flags } = await this.parse(RawCommand);
46
+ const rawFlags = { pretty: flags.pretty };
47
+ if (flags.workspace !== void 0) rawFlags.workspace = flags.workspace;
48
+ if (flags["allow-active-workspace-write"]) rawFlags["allow-active-workspace-write"] = flags["allow-active-workspace-write"];
49
+ if (flags["allow-mutations"]) rawFlags["allow-mutations"] = flags["allow-mutations"];
50
+ if (flags.vars !== void 0) rawFlags.vars = flags.vars;
51
+ const runArgs = {
52
+ commandPath: "raw",
53
+ pretty: flags.pretty ?? false,
54
+ handler: (retryOpts) => runRaw({
55
+ args,
56
+ flags: rawFlags,
57
+ env: process.env,
58
+ retryOptsOverride: retryOpts
59
+ })
60
+ };
61
+ if (flags.quiet !== void 0) runArgs.quiet = flags.quiet;
62
+ if (flags.noMeta !== void 0) runArgs.noMeta = flags.noMeta;
63
+ if (flags.retry !== void 0) runArgs.retry = flags.retry;
64
+ const out = await runCommand(runArgs);
65
+ if (!flags.json) process.stdout.write(out.stdout);
66
+ if (out.stderr) process.stderr.write(out.stderr);
67
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
68
+ return JSON.parse(out.stdout);
69
+ }
70
+ };
71
+ //#endregion
72
+ export { RawCommand as default, runRaw };
@@ -0,0 +1,69 @@
1
+ import { BASE_FLAGS, runCommand } from "../lib/workspace-runtime.js";
2
+ import { schemaRuntime } from "../lib/schema-runtime.js";
3
+ import { Command, Flags } from "@oclif/core";
4
+ //#region src/commands/schema.ts
5
+ /**
6
+ * `linmux schema` — Phase 4 PLAN 04-04, INT-03.
7
+ *
8
+ * Returns the Linear GraphQL schema without making any network calls.
9
+ * Sources the vendored `schema.graphql` via schema-loader.ts (lazy-cached).
10
+ *
11
+ * Default: compact SDL (triple-quoted descriptions stripped) for token efficiency.
12
+ * --full: SDL with all descriptions included.
13
+ * --json: Standard introspection JSON (__schema format) for programmatic tooling.
14
+ *
15
+ * No --workspace flag — this command makes zero network calls.
16
+ */
17
+ async function runSchema(args) {
18
+ const runArgs = {
19
+ commandPath: "schema",
20
+ pretty: args.pretty,
21
+ handler: async (_retryOpts) => {
22
+ return {
23
+ data: (await schemaRuntime({ flags: {
24
+ full: args.full,
25
+ json: args.json
26
+ } })).data,
27
+ meta: {}
28
+ };
29
+ }
30
+ };
31
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
32
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
33
+ if (args.retry !== void 0) runArgs.retry = args.retry;
34
+ return runCommand(runArgs);
35
+ }
36
+ var Schema = class Schema extends Command {
37
+ static description = "Return the Linear GraphQL schema as compact SDL (descriptions stripped by default), or as introspection JSON with --json.";
38
+ static enableJsonFlag = true;
39
+ static flags = {
40
+ ...BASE_FLAGS,
41
+ full: Flags.boolean({
42
+ description: "Include type descriptions in the SDL output (default: stripped for token efficiency)",
43
+ default: false
44
+ }),
45
+ json: Flags.boolean({
46
+ description: "Return introspection JSON (__schema format) instead of SDL text",
47
+ default: false,
48
+ char: "j"
49
+ })
50
+ };
51
+ async run() {
52
+ const { flags } = await this.parse(Schema);
53
+ const callArgs = {
54
+ pretty: flags.pretty,
55
+ full: flags.full,
56
+ json: flags.json
57
+ };
58
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
59
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
60
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
61
+ const out = await runSchema(callArgs);
62
+ if (!flags.json) process.stdout.write(out.stdout);
63
+ if (out.stderr) process.stderr.write(out.stderr);
64
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
65
+ return JSON.parse(out.stdout);
66
+ }
67
+ };
68
+ //#endregion
69
+ export { Schema as default, runSchema };
@@ -0,0 +1,77 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { PAGINATION_FLAGS } from "../../core/pagination/flags.js";
3
+ import "../../core/pagination/index.js";
4
+ import { stateListRuntime } from "../../lib/state-list-runtime.js";
5
+ import { Command, Flags } from "@oclif/core";
6
+ //#region src/commands/state/list.ts
7
+ /**
8
+ * `linmux state list` -- Phase 2 PLAN 02-09 Task 1, STA-01.
9
+ *
10
+ * Read command. Lists workflow states either across all teams the viewer can
11
+ * see (no filter) OR scoped to one team via `--team` (UUID, key, or name).
12
+ * Per CONTEXT § Specifics line 116, `--team` is OPTIONAL.
13
+ *
14
+ * Implementation lives in `src/lib/state-list-runtime.ts` per the Phase 1
15
+ * PLAN-04 invariant. Exports BOTH the default Command class AND a named
16
+ * `runStateList(args)` function.
17
+ */
18
+ async function runStateList(args) {
19
+ const runArgs = {
20
+ commandPath: "state list",
21
+ pretty: args.pretty,
22
+ handler: async (retryOpts) => {
23
+ const runtimeFlags = {};
24
+ if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
25
+ if (args.fields !== void 0) runtimeFlags.fields = args.fields;
26
+ if (args.limit !== void 0) runtimeFlags.limit = args.limit;
27
+ if (args.cursor !== void 0) runtimeFlags.cursor = args.cursor;
28
+ if (args.team !== void 0) runtimeFlags.team = args.team;
29
+ const result = await stateListRuntime({
30
+ flags: runtimeFlags,
31
+ env: process.env,
32
+ retryOptsOverride: retryOpts
33
+ });
34
+ return {
35
+ data: result.data,
36
+ meta: result.meta
37
+ };
38
+ }
39
+ };
40
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
41
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
42
+ if (args.retry !== void 0) runArgs.retry = args.retry;
43
+ return runCommand(runArgs);
44
+ }
45
+ var StateList = class StateList extends Command {
46
+ static description = "List Linear workflow states. Pass --team <UUID|key|name> to scope to one team; otherwise lists all states the viewer can see.";
47
+ static enableJsonFlag = true;
48
+ static flags = {
49
+ ...BASE_FLAGS,
50
+ ...PAGINATION_FLAGS,
51
+ workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
52
+ fields: Flags.string({
53
+ description: "Field preset (ids|defaults|full) or comma-separated list",
54
+ default: "defaults"
55
+ }),
56
+ team: Flags.string({ description: "Optional team filter (UUID, key, or name)" })
57
+ };
58
+ async run() {
59
+ const { flags } = await this.parse(StateList);
60
+ const callArgs = { pretty: flags.pretty };
61
+ if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
62
+ if (flags.fields !== void 0) callArgs.fields = flags.fields;
63
+ if (flags.limit !== void 0) callArgs.limit = flags.limit;
64
+ if (flags.cursor !== void 0) callArgs.cursor = flags.cursor;
65
+ if (flags.team !== void 0) callArgs.team = flags.team;
66
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
67
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
68
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
69
+ const out = await runStateList(callArgs);
70
+ if (!flags.json) process.stdout.write(out.stdout);
71
+ if (out.stderr) process.stderr.write(out.stderr);
72
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
73
+ return JSON.parse(out.stdout);
74
+ }
75
+ };
76
+ //#endregion
77
+ export { StateList as default, runStateList };
@@ -0,0 +1,73 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { teamGetRuntime } from "../../lib/team-get-runtime.js";
3
+ import { Args, Command, Flags } from "@oclif/core";
4
+ //#region src/commands/team/get.ts
5
+ /**
6
+ * `linmux team get <ref>` -- Phase 2 PLAN 02-09 Task 1, TEM-01.get.
7
+ *
8
+ * Single-entity read. Accepts a UUID, team key (e.g. `ENG`), or team name.
9
+ * Implementation lives in `src/lib/team-get-runtime.ts`.
10
+ *
11
+ * Exports BOTH the default Command class AND a named `runTeamGet(args)`
12
+ * function.
13
+ */
14
+ async function runTeamGet(args) {
15
+ const runArgs = {
16
+ commandPath: "team get",
17
+ pretty: args.pretty,
18
+ handler: async (retryOpts) => {
19
+ const runtimeFlags = {};
20
+ if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
21
+ if (args.fields !== void 0) runtimeFlags.fields = args.fields;
22
+ const result = await teamGetRuntime({
23
+ args: { ref: args.ref },
24
+ flags: runtimeFlags,
25
+ env: process.env,
26
+ retryOptsOverride: retryOpts
27
+ });
28
+ return {
29
+ data: result.data,
30
+ meta: result.meta
31
+ };
32
+ }
33
+ };
34
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
35
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
36
+ if (args.retry !== void 0) runArgs.retry = args.retry;
37
+ return runCommand(runArgs);
38
+ }
39
+ var TeamGet = class TeamGet extends Command {
40
+ static description = "Get a single Linear team by UUID, key (e.g. ENG), or name.";
41
+ static enableJsonFlag = true;
42
+ static args = { ref: Args.string({
43
+ required: true,
44
+ description: "Team UUID, key (e.g. ENG), or name"
45
+ }) };
46
+ static flags = {
47
+ ...BASE_FLAGS,
48
+ workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
49
+ fields: Flags.string({
50
+ description: "Field preset (ids|defaults|full) or comma-separated list",
51
+ default: "defaults"
52
+ })
53
+ };
54
+ async run() {
55
+ const { args, flags } = await this.parse(TeamGet);
56
+ const callArgs = {
57
+ ref: args.ref,
58
+ pretty: flags.pretty
59
+ };
60
+ if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
61
+ if (flags.fields !== void 0) callArgs.fields = flags.fields;
62
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
63
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
64
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
65
+ const out = await runTeamGet(callArgs);
66
+ if (!flags.json) process.stdout.write(out.stdout);
67
+ if (out.stderr) process.stderr.write(out.stderr);
68
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
69
+ return JSON.parse(out.stdout);
70
+ }
71
+ };
72
+ //#endregion
73
+ export { TeamGet as default, runTeamGet };
@@ -0,0 +1,73 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { PAGINATION_FLAGS } from "../../core/pagination/flags.js";
3
+ import "../../core/pagination/index.js";
4
+ import { teamListRuntime } from "../../lib/team-list-runtime.js";
5
+ import { Command, Flags } from "@oclif/core";
6
+ //#region src/commands/team/list.ts
7
+ /**
8
+ * `linmux team list` -- Phase 2 PLAN 02-09 Task 1, TEM-01.list.
9
+ *
10
+ * Read command. Lists workspace-scoped teams. Implementation lives in
11
+ * `src/lib/team-list-runtime.ts` per the Phase 1 PLAN-04 invariant (oclif
12
+ * scans every file under `src/commands/` as a Command class).
13
+ *
14
+ * Exports BOTH the default Command class AND a named `runTeamList(args)`
15
+ * function.
16
+ */
17
+ async function runTeamList(args) {
18
+ const runArgs = {
19
+ commandPath: "team list",
20
+ pretty: args.pretty,
21
+ handler: async (retryOpts) => {
22
+ const runtimeFlags = {};
23
+ if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
24
+ if (args.fields !== void 0) runtimeFlags.fields = args.fields;
25
+ if (args.limit !== void 0) runtimeFlags.limit = args.limit;
26
+ if (args.cursor !== void 0) runtimeFlags.cursor = args.cursor;
27
+ const result = await teamListRuntime({
28
+ flags: runtimeFlags,
29
+ env: process.env,
30
+ retryOptsOverride: retryOpts
31
+ });
32
+ return {
33
+ data: result.data,
34
+ meta: result.meta
35
+ };
36
+ }
37
+ };
38
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
39
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
40
+ if (args.retry !== void 0) runArgs.retry = args.retry;
41
+ return runCommand(runArgs);
42
+ }
43
+ var TeamList = class TeamList extends Command {
44
+ static description = "List Linear teams in the resolved workspace.";
45
+ static enableJsonFlag = true;
46
+ static flags = {
47
+ ...BASE_FLAGS,
48
+ ...PAGINATION_FLAGS,
49
+ workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
50
+ fields: Flags.string({
51
+ description: "Field preset (ids|defaults|full) or comma-separated list",
52
+ default: "defaults"
53
+ })
54
+ };
55
+ async run() {
56
+ const { flags } = await this.parse(TeamList);
57
+ const callArgs = { pretty: flags.pretty };
58
+ if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
59
+ if (flags.fields !== void 0) callArgs.fields = flags.fields;
60
+ if (flags.limit !== void 0) callArgs.limit = flags.limit;
61
+ if (flags.cursor !== void 0) callArgs.cursor = flags.cursor;
62
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
63
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
64
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
65
+ const out = await runTeamList(callArgs);
66
+ if (!flags.json) process.stdout.write(out.stdout);
67
+ if (out.stderr) process.stderr.write(out.stderr);
68
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
69
+ return JSON.parse(out.stdout);
70
+ }
71
+ };
72
+ //#endregion
73
+ export { TeamList as default, runTeamList };
@@ -0,0 +1,71 @@
1
+ import { BASE_FLAGS, runCommand } from "../lib/workspace-runtime.js";
2
+ import { meRuntime } from "../lib/me-runtime.js";
3
+ import { Command, Flags } from "@oclif/core";
4
+ //#region src/commands/whoami.ts
5
+ /**
6
+ * `linmux whoami` -- Phase 2 PLAN 02-09 Task 1, WHO-01.
7
+ *
8
+ * Alias for `me` -- prints the resolved viewer (user) and organization for
9
+ * the current workspace. Shares `src/lib/me-runtime.ts` with `me`. Both
10
+ * commands emit IDENTICAL envelopes except for `meta.command` (`'me'` vs
11
+ * `'whoami'`). `whoami` exists purely for discoverability per CONTEXT
12
+ * § Specifics line 65 (the pretty-alias pattern).
13
+ *
14
+ * Exports BOTH the default Command class AND a named `runWhoami(args)`
15
+ * function.
16
+ */
17
+ async function runWhoami(args) {
18
+ const runArgs = {
19
+ commandPath: "whoami",
20
+ pretty: args.pretty,
21
+ handler: async (retryOpts) => {
22
+ const runtimeFlags = {};
23
+ if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
24
+ if (args.fields !== void 0) runtimeFlags.fields = args.fields;
25
+ const meInput = {
26
+ flags: runtimeFlags,
27
+ env: process.env,
28
+ retryOptsOverride: retryOpts
29
+ };
30
+ if (args.loadConfigOverride !== void 0) meInput.loadConfigOverride = args.loadConfigOverride;
31
+ if (args.clientFactoryOverride !== void 0) meInput.clientFactoryOverride = args.clientFactoryOverride;
32
+ const result = await meRuntime(meInput);
33
+ return {
34
+ data: result.data,
35
+ meta: result.meta
36
+ };
37
+ }
38
+ };
39
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
40
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
41
+ if (args.retry !== void 0) runArgs.retry = args.retry;
42
+ return runCommand(runArgs);
43
+ }
44
+ var Whoami = class Whoami extends Command {
45
+ static description = "Alias for `me` -- prints the resolved viewer + organization.";
46
+ static enableJsonFlag = true;
47
+ static flags = {
48
+ ...BASE_FLAGS,
49
+ workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
50
+ fields: Flags.string({
51
+ description: "Field preset (ids|defaults|full) or comma-separated list",
52
+ default: "defaults"
53
+ })
54
+ };
55
+ async run() {
56
+ const { flags } = await this.parse(Whoami);
57
+ const callArgs = { pretty: flags.pretty };
58
+ if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
59
+ if (flags.fields !== void 0) callArgs.fields = flags.fields;
60
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
61
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
62
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
63
+ const out = await runWhoami(callArgs);
64
+ if (!flags.json) process.stdout.write(out.stdout);
65
+ if (out.stderr) process.stderr.write(out.stderr);
66
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
67
+ return JSON.parse(out.stdout);
68
+ }
69
+ };
70
+ //#endregion
71
+ export { Whoami as default, runWhoami };
@@ -0,0 +1,97 @@
1
+ import { LinearAgentError } from "../../core/errors/error.js";
2
+ import { withFetchInterception } from "../../core/transport/fetch-interceptor.js";
3
+ import { withRateLimitRetry } from "../../core/transport/rate-limit.js";
4
+ import "../../core/transport/index.js";
5
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
6
+ import { createLinearClient } from "../../core/client/factory.js";
7
+ import "../../core/client/index.js";
8
+ import { loadConfig, saveConfig } from "../../core/config/store.js";
9
+ import "../../core/config/index.js";
10
+ import { Args, Command, Flags } from "@oclif/core";
11
+ //#region src/commands/workspace/add.ts
12
+ async function runWorkspaceAdd(args) {
13
+ const runArgs = {
14
+ commandPath: "workspace add",
15
+ pretty: args.pretty,
16
+ handler: async (retryOpts) => {
17
+ const config = loadConfig();
18
+ if (Object.hasOwn(config.workspaces, args.name)) throw LinearAgentError.workspace.alreadyExists(args.name);
19
+ const client = createLinearClient({
20
+ name: null,
21
+ token: args.token,
22
+ organizationId: null,
23
+ source: "api-key-env"
24
+ });
25
+ const effectiveRetryOpts = args.retryOptsOverride ?? retryOpts;
26
+ const orgId = await withFetchInterception(async () => {
27
+ const viewer = await withRateLimitRetry(() => client.viewer, effectiveRetryOpts);
28
+ return (await withRateLimitRetry(() => viewer.organization, effectiveRetryOpts)).id;
29
+ });
30
+ let warning;
31
+ const collision = Object.values(config.workspaces).find((w) => w.organizationId === orgId);
32
+ if (collision) warning = `organization already registered as ${collision.name}`;
33
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
34
+ const entry = {
35
+ name: args.name,
36
+ token: args.token,
37
+ organizationId: orgId,
38
+ createdAt
39
+ };
40
+ const isActive = Object.keys(config.workspaces).length === 0;
41
+ saveConfig({
42
+ active: isActive ? args.name : config.active,
43
+ workspaces: {
44
+ ...config.workspaces,
45
+ [args.name]: entry
46
+ }
47
+ });
48
+ return {
49
+ data: {
50
+ name: args.name,
51
+ organizationId: orgId,
52
+ isActive,
53
+ createdAt,
54
+ ...warning !== void 0 ? { warning } : {}
55
+ },
56
+ meta: { workspace: args.name }
57
+ };
58
+ }
59
+ };
60
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
61
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
62
+ if (args.retry !== void 0) runArgs.retry = args.retry;
63
+ return runCommand(runArgs);
64
+ }
65
+ var WorkspaceAdd = class WorkspaceAdd extends Command {
66
+ static description = "Register a Linear workspace";
67
+ static enableJsonFlag = true;
68
+ static args = { name: Args.string({
69
+ required: true,
70
+ description: "Local alias for the workspace"
71
+ }) };
72
+ static flags = {
73
+ token: Flags.string({
74
+ required: true,
75
+ description: "Linear personal API key (lin_api_*)"
76
+ }),
77
+ ...BASE_FLAGS
78
+ };
79
+ async run() {
80
+ const { args, flags } = await this.parse(WorkspaceAdd);
81
+ const callArgs = {
82
+ name: args.name,
83
+ token: flags.token,
84
+ pretty: flags.pretty
85
+ };
86
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
87
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
88
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
89
+ const out = await runWorkspaceAdd(callArgs);
90
+ if (!flags.json) process.stdout.write(out.stdout);
91
+ if (out.stderr) process.stderr.write(out.stderr);
92
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
93
+ return JSON.parse(out.stdout);
94
+ }
95
+ };
96
+ //#endregion
97
+ export { WorkspaceAdd as default, runWorkspaceAdd };
@@ -0,0 +1,47 @@
1
+ import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
2
+ import { loadConfig } from "../../core/config/store.js";
3
+ import "../../core/config/index.js";
4
+ import { Command } from "@oclif/core";
5
+ //#region src/commands/workspace/list.ts
6
+ async function runWorkspaceList(args) {
7
+ const runArgs = {
8
+ commandPath: "workspace list",
9
+ pretty: args.pretty,
10
+ handler: async (_retryOpts) => {
11
+ const config = loadConfig();
12
+ return {
13
+ data: { workspaces: Object.values(config.workspaces).sort((a, b) => a.name.localeCompare(b.name)).map((w) => ({
14
+ name: w.name,
15
+ organizationId: w.organizationId,
16
+ isActive: config.active === w.name,
17
+ createdAt: w.createdAt,
18
+ ...w.lastUsedAt !== void 0 ? { lastUsedAt: w.lastUsedAt } : {}
19
+ })) },
20
+ meta: {}
21
+ };
22
+ }
23
+ };
24
+ if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
25
+ if (args.quiet !== void 0) runArgs.quiet = args.quiet;
26
+ if (args.retry !== void 0) runArgs.retry = args.retry;
27
+ return runCommand(runArgs);
28
+ }
29
+ var WorkspaceList = class WorkspaceList extends Command {
30
+ static description = "List registered Linear workspaces";
31
+ static enableJsonFlag = true;
32
+ static flags = { ...BASE_FLAGS };
33
+ async run() {
34
+ const { flags } = await this.parse(WorkspaceList);
35
+ const callArgs = { pretty: flags.pretty };
36
+ if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
37
+ if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
38
+ if (flags.retry !== void 0) callArgs.retry = flags.retry;
39
+ const out = await runWorkspaceList(callArgs);
40
+ if (!flags.json) process.stdout.write(out.stdout);
41
+ if (out.stderr) process.stderr.write(out.stderr);
42
+ if (out.exitCode !== 0) process.exitCode = out.exitCode;
43
+ return JSON.parse(out.stdout);
44
+ }
45
+ };
46
+ //#endregion
47
+ export { WorkspaceList as default, runWorkspaceList };