@sanity/cli 8.22.1 → 8.23.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 (83) hide show
  1. package/dist/actions/context/watchJob.js +9 -3
  2. package/dist/actions/context/watchJob.js.map +1 -1
  3. package/dist/actions/deploy/blueprintManaged.js +59 -0
  4. package/dist/actions/deploy/blueprintManaged.js.map +1 -0
  5. package/dist/actions/deploy/deployApp.js +117 -1
  6. package/dist/actions/deploy/deployApp.js.map +1 -1
  7. package/dist/actions/deploy/deployRunner.js.map +1 -1
  8. package/dist/actions/deploy/deployStudio.js +6 -31
  9. package/dist/actions/deploy/deployStudio.js.map +1 -1
  10. package/dist/actions/exec/runScript.worker.js +6 -2
  11. package/dist/actions/exec/runScript.worker.js.map +1 -1
  12. package/dist/actions/init/bootstrapLocalTemplate.js +35 -11
  13. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  14. package/dist/actions/init/createMediaLibraryCliConfig.js +12 -0
  15. package/dist/actions/init/createMediaLibraryCliConfig.js.map +1 -0
  16. package/dist/actions/init/determineMediaLibraryTemplate.js +14 -0
  17. package/dist/actions/init/determineMediaLibraryTemplate.js.map +1 -0
  18. package/dist/actions/init/initAction.js +35 -6
  19. package/dist/actions/init/initAction.js.map +1 -1
  20. package/dist/actions/init/initApp.js +81 -6
  21. package/dist/actions/init/initApp.js.map +1 -1
  22. package/dist/actions/init/offerAspectPull.js +81 -0
  23. package/dist/actions/init/offerAspectPull.js.map +1 -0
  24. package/dist/actions/init/project/getProjectDetails.js +25 -2
  25. package/dist/actions/init/project/getProjectDetails.js.map +1 -1
  26. package/dist/actions/init/templates/index.js +3 -0
  27. package/dist/actions/init/templates/index.js.map +1 -1
  28. package/dist/actions/init/templates/mediaLibraryConfig.js +51 -0
  29. package/dist/actions/init/templates/mediaLibraryConfig.js.map +1 -0
  30. package/dist/actions/media/aspectName.js +8 -0
  31. package/dist/actions/media/aspectName.js.map +1 -0
  32. package/dist/actions/media/aspectSync/contract.js +163 -0
  33. package/dist/actions/media/aspectSync/contract.js.map +1 -0
  34. package/dist/actions/media/aspectSync/syncAspects.js +115 -0
  35. package/dist/actions/media/aspectSync/syncAspects.js.map +1 -0
  36. package/dist/actions/media/cliConfigFields.js +192 -0
  37. package/dist/actions/media/cliConfigFields.js.map +1 -0
  38. package/dist/actions/media/pullAspects.js +225 -0
  39. package/dist/actions/media/pullAspects.js.map +1 -0
  40. package/dist/actions/media/resolveMediaLibraryId.js +83 -0
  41. package/dist/actions/media/resolveMediaLibraryId.js.map +1 -0
  42. package/dist/commands/context/build.js +2 -2
  43. package/dist/commands/context/build.js.map +1 -1
  44. package/dist/commands/context/entries/get.js +83 -0
  45. package/dist/commands/context/entries/get.js.map +1 -0
  46. package/dist/commands/context/entries/list.js +82 -0
  47. package/dist/commands/context/entries/list.js.map +1 -0
  48. package/dist/commands/context/entries/rebuild.js +95 -0
  49. package/dist/commands/context/entries/rebuild.js.map +1 -0
  50. package/dist/commands/context/issues/apply.js +86 -0
  51. package/dist/commands/context/issues/apply.js.map +1 -0
  52. package/dist/commands/context/issues/dismiss.js +52 -0
  53. package/dist/commands/context/issues/dismiss.js.map +1 -0
  54. package/dist/commands/context/issues/get.js +105 -0
  55. package/dist/commands/context/issues/get.js.map +1 -0
  56. package/dist/commands/context/issues/list.js +128 -0
  57. package/dist/commands/context/issues/list.js.map +1 -0
  58. package/dist/commands/context/issues/reopen.js +53 -0
  59. package/dist/commands/context/issues/reopen.js.map +1 -0
  60. package/dist/commands/context/issues/resolve.js +137 -0
  61. package/dist/commands/context/issues/resolve.js.map +1 -0
  62. package/dist/commands/context/jobs/get.js +2 -2
  63. package/dist/commands/context/jobs/get.js.map +1 -1
  64. package/dist/commands/context/query.js +92 -0
  65. package/dist/commands/context/query.js.map +1 -0
  66. package/dist/commands/deploy.js +13 -0
  67. package/dist/commands/deploy.js.map +1 -1
  68. package/dist/commands/media/prune-aspect-data.js +170 -0
  69. package/dist/commands/media/prune-aspect-data.js.map +1 -0
  70. package/dist/commands/media/pull-aspects.js +309 -0
  71. package/dist/commands/media/pull-aspects.js.map +1 -0
  72. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +17 -0
  73. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
  74. package/dist/services/context.js +96 -3
  75. package/dist/services/context.js.map +1 -1
  76. package/dist/services/mediaLibraries.js +175 -8
  77. package/dist/services/mediaLibraries.js.map +1 -1
  78. package/oclif.manifest.json +2930 -2241
  79. package/package.json +6 -5
  80. package/templates/media-library-config/README.md +52 -0
  81. package/templates/media-library-config/eslint.config.txt +52 -0
  82. package/templates/media-library-config/src/fields/caption.tsx +29 -0
  83. package/templates/media-library-config/src/fields/notes.tsx +54 -0
@@ -0,0 +1,95 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { spinner } from '@sanity/cli-core/ux';
5
+ import { isHttpError } from '@sanity/client';
6
+ import { formatJobFailure, watchJob } from '../../../actions/context/watchJob.js';
7
+ import { formatKeyValue } from '../../../actions/debug/output.js';
8
+ import { rebuildEntry } from '../../../services/context.js';
9
+ const rebuildEntryDebug = subdebug('context:entries:rebuild');
10
+ export class RebuildEntryCommand extends SanityCommand {
11
+ static args = {
12
+ knowledgeBaseId: Args.string({
13
+ description: 'Knowledge base ID',
14
+ required: true
15
+ }),
16
+ path: Args.string({
17
+ description: 'Entry path, as listed by `sanity context entries list`',
18
+ required: true
19
+ })
20
+ };
21
+ static description = 'Rebuild one entry from its sources';
22
+ static examples = [
23
+ {
24
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 billing/refunds',
25
+ description: 'Start a rebuild and return the job ID'
26
+ },
27
+ {
28
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 billing/refunds --watch',
29
+ description: 'Rebuild an entry and wait for it to finish (non-zero exit on failure)'
30
+ }
31
+ ];
32
+ static flags = {
33
+ watch: Flags.boolean({
34
+ default: false,
35
+ description: 'Wait for the rebuild to finish, exiting non-zero if it fails'
36
+ })
37
+ };
38
+ async run() {
39
+ const { knowledgeBaseId, path } = this.args;
40
+ const { watch } = this.flags;
41
+ let accepted;
42
+ const spin = spinner('Starting rebuild').start();
43
+ try {
44
+ accepted = await rebuildEntry(knowledgeBaseId, path);
45
+ spin.succeed('Rebuild started');
46
+ } catch (error) {
47
+ spin.fail();
48
+ rebuildEntryDebug('Error starting rebuild', error);
49
+ if (isHttpError(error) && error.statusCode === 404) {
50
+ this.error(`Entry "${path}" not found on knowledge base "${knowledgeBaseId}"`, {
51
+ exit: exitCodes.RUNTIME_ERROR
52
+ });
53
+ }
54
+ this.error(`Failed to start rebuild: ${getErrorMessage(error)}`, {
55
+ exit: exitCodes.RUNTIME_ERROR
56
+ });
57
+ }
58
+ const { affectedEntries, jobId } = accepted;
59
+ const padTo = 19 // "Shares sources with" is the longest key
60
+ ;
61
+ this.log(formatKeyValue('Job ID', jobId, {
62
+ padTo
63
+ }));
64
+ // Other entries citing the same sources can change when they are next rebuilt
65
+ if (affectedEntries.length > 0) {
66
+ const paths = affectedEntries.map((entry)=>entry.path).join(', ');
67
+ this.log(formatKeyValue('Shares sources with', paths, {
68
+ padTo
69
+ }));
70
+ }
71
+ this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`);
72
+ if (!watch) {
73
+ return;
74
+ }
75
+ let job;
76
+ try {
77
+ job = await watchJob(knowledgeBaseId, jobId, {
78
+ label: 'Rebuilding entry',
79
+ successText: 'Entry rebuilt'
80
+ });
81
+ } catch (error) {
82
+ rebuildEntryDebug('Error watching rebuild job', error);
83
+ this.error(`Failed to watch rebuild job: ${getErrorMessage(error)}`, {
84
+ exit: exitCodes.RUNTIME_ERROR
85
+ });
86
+ }
87
+ if (job.status !== 'succeeded') {
88
+ this.error(formatJobFailure('Rebuild', job), {
89
+ exit: exitCodes.RUNTIME_ERROR
90
+ });
91
+ }
92
+ }
93
+ }
94
+
95
+ //# sourceMappingURL=rebuild.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/entries/rebuild.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatJobFailure, watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {rebuildEntry} from '../../../services/context.js'\n\nconst rebuildEntryDebug = subdebug('context:entries:rebuild')\n\nexport class RebuildEntryCommand extends SanityCommand<typeof RebuildEntryCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n path: Args.string({\n description: 'Entry path, as listed by `sanity context entries list`',\n required: true,\n }),\n }\n\n static override description = 'Rebuild one entry from its sources'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 billing/refunds',\n description: 'Start a rebuild and return the job ID',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 billing/refunds --watch',\n description: 'Rebuild an entry and wait for it to finish (non-zero exit on failure)',\n },\n ]\n\n static override flags = {\n watch: Flags.boolean({\n default: false,\n description: 'Wait for the rebuild to finish, exiting non-zero if it fails',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {knowledgeBaseId, path} = this.args\n const {watch} = this.flags\n\n let accepted\n const spin = spinner('Starting rebuild').start()\n try {\n accepted = await rebuildEntry(knowledgeBaseId, path)\n spin.succeed('Rebuild started')\n } catch (error) {\n spin.fail()\n rebuildEntryDebug('Error starting rebuild', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Entry \"${path}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to start rebuild: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const {affectedEntries, jobId} = accepted\n const padTo = 19 // \"Shares sources with\" is the longest key\n this.log(formatKeyValue('Job ID', jobId, {padTo}))\n // Other entries citing the same sources can change when they are next rebuilt\n if (affectedEntries.length > 0) {\n const paths = affectedEntries.map((entry) => entry.path).join(', ')\n this.log(formatKeyValue('Shares sources with', paths, {padTo}))\n }\n this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`)\n\n if (!watch) {\n return\n }\n\n let job\n try {\n job = await watchJob(knowledgeBaseId, jobId, {\n label: 'Rebuilding entry',\n successText: 'Entry rebuilt',\n })\n } catch (error) {\n rebuildEntryDebug('Error watching rebuild job', error)\n this.error(`Failed to watch rebuild job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (job.status !== 'succeeded') {\n this.error(formatJobFailure('Rebuild', job), {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","spinner","isHttpError","formatJobFailure","watchJob","formatKeyValue","rebuildEntry","rebuildEntryDebug","RebuildEntryCommand","args","knowledgeBaseId","string","description","required","path","examples","command","flags","watch","boolean","default","run","accepted","spin","start","succeed","error","fail","statusCode","exit","RUNTIME_ERROR","affectedEntries","jobId","padTo","log","length","paths","map","entry","join","job","label","successText","status"],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { spinner } from '@sanity/cli-core/ux';
5
+ import { isHttpError } from '@sanity/client';
6
+ import { formatJobFailure, watchJob } from '../../../actions/context/watchJob.js';
7
+ import { formatKeyValue } from '../../../actions/debug/output.js';
8
+ import { applyIssues } from '../../../services/context.js';
9
+ const applyIssuesDebug = subdebug('context:issues:apply');
10
+ export class ApplyIssuesCommand extends SanityCommand {
11
+ static args = {
12
+ knowledgeBaseId: Args.string({
13
+ description: 'Knowledge base ID',
14
+ required: true
15
+ }),
16
+ // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
17
+ issueId: Args.string({
18
+ description: "ID of an issue to accept and apply (pass several to apply them in one batch). Conflicts can't be applied; resolve them with `sanity context issues resolve`",
19
+ multiple: true,
20
+ required: true
21
+ })
22
+ };
23
+ static description = 'Accept and apply issues to a knowledge base';
24
+ static examples = [
25
+ {
26
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 issue.ghi789',
27
+ description: 'Accept and apply two issues in one batch'
28
+ },
29
+ {
30
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --watch',
31
+ description: 'Apply an issue and wait for it to finish (non-zero exit on failure)'
32
+ }
33
+ ];
34
+ static flags = {
35
+ watch: Flags.boolean({
36
+ default: false,
37
+ description: 'Wait for the apply to finish, exiting non-zero if it fails'
38
+ })
39
+ };
40
+ async run() {
41
+ const { issueId: issueIds, knowledgeBaseId } = this.args;
42
+ const { watch } = this.flags;
43
+ let jobId;
44
+ const spin = spinner('Starting apply').start();
45
+ try {
46
+ const accepted = await applyIssues(knowledgeBaseId, issueIds);
47
+ jobId = accepted.jobId;
48
+ spin.succeed('Apply started');
49
+ } catch (error) {
50
+ spin.fail();
51
+ applyIssuesDebug('Error applying issues', error);
52
+ if (isHttpError(error) && error.statusCode === 404) {
53
+ this.error(`Knowledge base "${knowledgeBaseId}" not found`, {
54
+ exit: exitCodes.RUNTIME_ERROR
55
+ });
56
+ }
57
+ this.error(`Failed to apply issues: ${getErrorMessage(error)}`, {
58
+ exit: exitCodes.RUNTIME_ERROR
59
+ });
60
+ }
61
+ this.log(formatKeyValue('Job ID', jobId));
62
+ this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`);
63
+ if (!watch) {
64
+ return;
65
+ }
66
+ let job;
67
+ try {
68
+ job = await watchJob(knowledgeBaseId, jobId, {
69
+ label: 'Applying issues',
70
+ successText: 'Issues applied'
71
+ });
72
+ } catch (error) {
73
+ applyIssuesDebug('Error watching apply job', error);
74
+ this.error(`Failed to watch apply job: ${getErrorMessage(error)}`, {
75
+ exit: exitCodes.RUNTIME_ERROR
76
+ });
77
+ }
78
+ if (job.status !== 'succeeded') {
79
+ this.error(formatJobFailure('Apply', job), {
80
+ exit: exitCodes.RUNTIME_ERROR
81
+ });
82
+ }
83
+ }
84
+ }
85
+
86
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/issues/apply.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatJobFailure, watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {applyIssues} from '../../../services/context.js'\n\nconst applyIssuesDebug = subdebug('context:issues:apply')\n\nexport class ApplyIssuesCommand extends SanityCommand<typeof ApplyIssuesCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description:\n \"ID of an issue to accept and apply (pass several to apply them in one batch). Conflicts can't be applied; resolve them with `sanity context issues resolve`\",\n multiple: true,\n required: true,\n }),\n }\n\n static override description = 'Accept and apply issues to a knowledge base'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 issue.ghi789',\n description: 'Accept and apply two issues in one batch',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --watch',\n description: 'Apply an issue and wait for it to finish (non-zero exit on failure)',\n },\n ]\n\n static override flags = {\n watch: Flags.boolean({\n default: false,\n description: 'Wait for the apply to finish, exiting non-zero if it fails',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {issueId: issueIds, knowledgeBaseId} = this.args\n const {watch} = this.flags\n\n let jobId: string\n const spin = spinner('Starting apply').start()\n try {\n const accepted = await applyIssues(knowledgeBaseId, issueIds)\n jobId = accepted.jobId\n spin.succeed('Apply started')\n } catch (error) {\n spin.fail()\n applyIssuesDebug('Error applying issues', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to apply issues: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n this.log(formatKeyValue('Job ID', jobId))\n this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`)\n\n if (!watch) {\n return\n }\n\n let job\n try {\n job = await watchJob(knowledgeBaseId, jobId, {\n label: 'Applying issues',\n successText: 'Issues applied',\n })\n } catch (error) {\n applyIssuesDebug('Error watching apply job', error)\n this.error(`Failed to watch apply job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (job.status !== 'succeeded') {\n this.error(formatJobFailure('Apply', job), {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","spinner","isHttpError","formatJobFailure","watchJob","formatKeyValue","applyIssues","applyIssuesDebug","ApplyIssuesCommand","args","knowledgeBaseId","string","description","required","issueId","multiple","examples","command","flags","watch","boolean","default","run","issueIds","jobId","spin","start","accepted","succeed","error","fail","statusCode","exit","RUNTIME_ERROR","log","job","label","successText","status"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,gBAAgB,EAAEC,QAAQ,QAAO,uCAAsC;AAC/E,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,WAAW,QAAO,+BAA8B;AAExD,MAAMC,mBAAmBR,SAAS;AAElC,OAAO,MAAMS,2BAA2BV;IACtC,OAAgBW,OAAO;QACrBC,iBAAiBf,KAAKgB,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,SAASnB,KAAKgB,MAAM,CAAC;YACnBC,aACE;YACFG,UAAU;YACVF,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,8CAA6C;IAE3E,OAAgBI,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,OAAgBM,QAAQ;QACtBC,OAAOvB,MAAMwB,OAAO,CAAC;YACnBC,SAAS;YACTT,aAAa;QACf;IACF,EAAqB;IAErB,MAAaU,MAAqB;QAChC,MAAM,EAACR,SAASS,QAAQ,EAAEb,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QACtD,MAAM,EAACU,KAAK,EAAC,GAAG,IAAI,CAACD,KAAK;QAE1B,IAAIM;QACJ,MAAMC,OAAOxB,QAAQ,kBAAkByB,KAAK;QAC5C,IAAI;YACF,MAAMC,WAAW,MAAMrB,YAAYI,iBAAiBa;YACpDC,QAAQG,SAASH,KAAK;YACtBC,KAAKG,OAAO,CAAC;QACf,EAAE,OAAOC,OAAO;YACdJ,KAAKK,IAAI;YACTvB,iBAAiB,yBAAyBsB;YAC1C,IAAI3B,YAAY2B,UAAUA,MAAME,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACF,KAAK,CAAC,CAAC,gBAAgB,EAAEnB,gBAAgB,WAAW,CAAC,EAAE;oBAC1DsB,MAAMnC,UAAUoC,aAAa;gBAC/B;YACF;YACA,IAAI,CAACJ,KAAK,CAAC,CAAC,wBAAwB,EAAE7B,gBAAgB6B,QAAQ,EAAE;gBAC9DG,MAAMnC,UAAUoC,aAAa;YAC/B;QACF;QAEA,IAAI,CAACC,GAAG,CAAC7B,eAAe,UAAUmB;QAClC,IAAI,CAACU,GAAG,CAAC,CAAC,uCAAuC,EAAExB,gBAAgB,CAAC,EAAEc,OAAO;QAE7E,IAAI,CAACL,OAAO;YACV;QACF;QAEA,IAAIgB;QACJ,IAAI;YACFA,MAAM,MAAM/B,SAASM,iBAAiBc,OAAO;gBAC3CY,OAAO;gBACPC,aAAa;YACf;QACF,EAAE,OAAOR,OAAO;YACdtB,iBAAiB,4BAA4BsB;YAC7C,IAAI,CAACA,KAAK,CAAC,CAAC,2BAA2B,EAAE7B,gBAAgB6B,QAAQ,EAAE;gBACjEG,MAAMnC,UAAUoC,aAAa;YAC/B;QACF;QAEA,IAAIE,IAAIG,MAAM,KAAK,aAAa;YAC9B,IAAI,CAACT,KAAK,CAAC1B,iBAAiB,SAASgC,MAAM;gBACzCH,MAAMnC,UAAUoC,aAAa;YAC/B;QACF;IACF;AACF"}
@@ -0,0 +1,52 @@
1
+ import { Args } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { isHttpError } from '@sanity/client';
5
+ import { dismissIssue } from '../../../services/context.js';
6
+ const dismissIssueDebug = subdebug('context:issues:dismiss');
7
+ export class DismissIssueCommand extends SanityCommand {
8
+ static args = {
9
+ knowledgeBaseId: Args.string({
10
+ description: 'Knowledge base ID',
11
+ required: true
12
+ }),
13
+ // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
14
+ issueId: Args.string({
15
+ description: 'Issue ID',
16
+ required: true
17
+ })
18
+ };
19
+ static description = "Dismiss an issue\n\nDismissing is permanent: dismissed issues can't be reopened.";
20
+ static examples = [
21
+ {
22
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',
23
+ description: 'Dismiss an issue'
24
+ }
25
+ ];
26
+ async run() {
27
+ const { issueId, knowledgeBaseId } = this.args;
28
+ let dismissed;
29
+ try {
30
+ dismissed = await dismissIssue(knowledgeBaseId, issueId);
31
+ } catch (error) {
32
+ dismissIssueDebug('Error dismissing issue', error);
33
+ if (isHttpError(error) && error.statusCode === 404) {
34
+ this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
35
+ exit: exitCodes.RUNTIME_ERROR
36
+ });
37
+ }
38
+ this.error(`Failed to dismiss issue: ${getErrorMessage(error)}`, {
39
+ exit: exitCodes.RUNTIME_ERROR
40
+ });
41
+ }
42
+ // The API returns the issue unchanged when it already left triage
43
+ if (dismissed.status !== 'rejected') {
44
+ this.error(`Issue "${issueId}" is accepted (resolved or applied) and cannot be dismissed`, {
45
+ exit: exitCodes.RUNTIME_ERROR
46
+ });
47
+ }
48
+ this.log('Issue dismissed');
49
+ }
50
+ }
51
+
52
+ //# sourceMappingURL=dismiss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/issues/dismiss.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {dismissIssue} from '../../../services/context.js'\n\nconst dismissIssueDebug = subdebug('context:issues:dismiss')\n\nexport class DismissIssueCommand extends SanityCommand<typeof DismissIssueCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description: 'Issue ID',\n required: true,\n }),\n }\n\n static override description =\n \"Dismiss an issue\\n\\nDismissing is permanent: dismissed issues can't be reopened.\"\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',\n description: 'Dismiss an issue',\n },\n ]\n\n public async run(): Promise<void> {\n const {issueId, knowledgeBaseId} = this.args\n\n let dismissed\n try {\n dismissed = await dismissIssue(knowledgeBaseId, issueId)\n } catch (error) {\n dismissIssueDebug('Error dismissing issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to dismiss issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // The API returns the issue unchanged when it already left triage\n if (dismissed.status !== 'rejected') {\n this.error(`Issue \"${issueId}\" is accepted (resolved or applied) and cannot be dismissed`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n this.log('Issue dismissed')\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","dismissIssue","dismissIssueDebug","DismissIssueCommand","args","knowledgeBaseId","string","description","required","issueId","examples","command","run","dismissed","error","statusCode","exit","RUNTIME_ERROR","status","log"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,YAAY,QAAO,+BAA8B;AAEzD,MAAMC,oBAAoBJ,SAAS;AAEnC,OAAO,MAAMK,4BAA4BN;IACvC,OAAgBO,OAAO;QACrBC,iBAAiBV,KAAKW,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,SAASd,KAAKW,MAAM,CAAC;YACnBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cACd,mFAAkF;IAEpF,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,MAAaK,MAAqB;QAChC,MAAM,EAACH,OAAO,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAE5C,IAAIS;QACJ,IAAI;YACFA,YAAY,MAAMZ,aAAaI,iBAAiBI;QAClD,EAAE,OAAOK,OAAO;YACdZ,kBAAkB,0BAA0BY;YAC5C,IAAId,YAAYc,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,OAAO,EAAEL,QAAQ,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAChFW,MAAMpB,UAAUqB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,yBAAyB,EAAEf,gBAAgBe,QAAQ,EAAE;gBAC/DE,MAAMpB,UAAUqB,aAAa;YAC/B;QACF;QAEA,kEAAkE;QAClE,IAAIJ,UAAUK,MAAM,KAAK,YAAY;YACnC,IAAI,CAACJ,KAAK,CAAC,CAAC,OAAO,EAAEL,QAAQ,2DAA2D,CAAC,EAAE;gBACzFO,MAAMpB,UAAUqB,aAAa;YAC/B;QACF;QAEA,IAAI,CAACE,GAAG,CAAC;IACX;AACF"}
@@ -0,0 +1,105 @@
1
+ import { Args } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { isHttpError } from '@sanity/client';
5
+ import { formatKeyValue } from '../../../actions/debug/output.js';
6
+ import { getIssue } from '../../../services/context.js';
7
+ const getIssueDebug = subdebug('context:issues:get');
8
+ export class GetIssueCommand extends SanityCommand {
9
+ static args = {
10
+ knowledgeBaseId: Args.string({
11
+ description: 'Knowledge base ID',
12
+ required: true
13
+ }),
14
+ // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
15
+ issueId: Args.string({
16
+ description: 'Issue ID',
17
+ required: true
18
+ })
19
+ };
20
+ static description = 'Get details of an issue';
21
+ static enableJsonFlag = true;
22
+ static examples = [
23
+ {
24
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',
25
+ description: 'Get details of a specific issue'
26
+ },
27
+ {
28
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --json',
29
+ description: 'Output the issue as JSON'
30
+ }
31
+ ];
32
+ async run() {
33
+ const { issueId, knowledgeBaseId } = this.args;
34
+ const { json } = this.flags;
35
+ let issue;
36
+ try {
37
+ issue = await getIssue(knowledgeBaseId, issueId);
38
+ } catch (error) {
39
+ getIssueDebug('Error getting issue', error);
40
+ if (isHttpError(error) && error.statusCode === 404) {
41
+ this.error(`Knowledge base "${knowledgeBaseId}" not found`, {
42
+ exit: exitCodes.RUNTIME_ERROR
43
+ });
44
+ }
45
+ this.error(`Failed to get issue: ${getErrorMessage(error)}`, {
46
+ exit: exitCodes.RUNTIME_ERROR
47
+ });
48
+ }
49
+ if (!issue) {
50
+ this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
51
+ exit: exitCodes.RUNTIME_ERROR
52
+ });
53
+ }
54
+ if (json) {
55
+ this.logJson(issue);
56
+ return;
57
+ }
58
+ const { content } = issue;
59
+ const padTo = 13 // "Suggested fix" is the longest key
60
+ ;
61
+ this.log(formatKeyValue('ID', issue._id, {
62
+ padTo
63
+ }));
64
+ this.log(formatKeyValue('Kind', content.kind, {
65
+ padTo
66
+ }));
67
+ this.log(formatKeyValue('Severity', content.severity, {
68
+ padTo
69
+ }));
70
+ this.log(formatKeyValue('Status', issue.status, {
71
+ padTo
72
+ }));
73
+ this.log(formatKeyValue('Scope', content.scopePath, {
74
+ padTo
75
+ }));
76
+ this.log(formatKeyValue('Issue', content.issue, {
77
+ padTo
78
+ }));
79
+ this.log(formatKeyValue('Suggested fix', content.suggestedFix, {
80
+ padTo
81
+ }));
82
+ // Sides are labeled with the 0-based index that `issues resolve --side` takes
83
+ if (content.kind === 'conflict') {
84
+ for (const [index, side] of content.sides.entries()){
85
+ const entryPaths = side.entryPaths?.length ? ` (${side.entryPaths.join(', ')})` : '';
86
+ this.log(formatKeyValue(`Side [${index}]`, `${side.claim}${entryPaths}`, {
87
+ padTo
88
+ }));
89
+ }
90
+ if (content.suggested !== undefined) {
91
+ this.log(formatKeyValue('Suggested', `[${content.suggested}]`, {
92
+ padTo
93
+ }));
94
+ }
95
+ }
96
+ this.log(formatKeyValue('Resolution', issue.resolution === null ? '-' : `[${issue.resolution}]`, {
97
+ padTo
98
+ }));
99
+ this.log(formatKeyValue('Created', issue._createdAt, {
100
+ padTo
101
+ }));
102
+ }
103
+ }
104
+
105
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/issues/get.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getIssue} from '../../../services/context.js'\n\nconst getIssueDebug = subdebug('context:issues:get')\n\nexport class GetIssueCommand extends SanityCommand<typeof GetIssueCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description: 'Issue ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of an issue'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',\n description: 'Get details of a specific issue',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --json',\n description: 'Output the issue as JSON',\n },\n ]\n\n public async run(): Promise<void> {\n const {issueId, knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let issue\n try {\n issue = await getIssue(knowledgeBaseId, issueId)\n } catch (error) {\n getIssueDebug('Error getting issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!issue) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(issue)\n return\n }\n\n const {content} = issue\n const padTo = 13 // \"Suggested fix\" is the longest key\n this.log(formatKeyValue('ID', issue._id, {padTo}))\n this.log(formatKeyValue('Kind', content.kind, {padTo}))\n this.log(formatKeyValue('Severity', content.severity, {padTo}))\n this.log(formatKeyValue('Status', issue.status, {padTo}))\n this.log(formatKeyValue('Scope', content.scopePath, {padTo}))\n this.log(formatKeyValue('Issue', content.issue, {padTo}))\n this.log(formatKeyValue('Suggested fix', content.suggestedFix, {padTo}))\n // Sides are labeled with the 0-based index that `issues resolve --side` takes\n if (content.kind === 'conflict') {\n for (const [index, side] of content.sides.entries()) {\n const entryPaths = side.entryPaths?.length ? ` (${side.entryPaths.join(', ')})` : ''\n this.log(formatKeyValue(`Side [${index}]`, `${side.claim}${entryPaths}`, {padTo}))\n }\n if (content.suggested !== undefined) {\n this.log(formatKeyValue('Suggested', `[${content.suggested}]`, {padTo}))\n }\n }\n this.log(\n formatKeyValue('Resolution', issue.resolution === null ? '-' : `[${issue.resolution}]`, {\n padTo,\n }),\n )\n this.log(formatKeyValue('Created', issue._createdAt, {padTo}))\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","getIssue","getIssueDebug","GetIssueCommand","args","knowledgeBaseId","string","description","required","issueId","enableJsonFlag","examples","command","run","json","flags","issue","error","statusCode","exit","RUNTIME_ERROR","logJson","content","padTo","log","_id","kind","severity","status","scopePath","suggestedFix","index","side","sides","entries","entryPaths","length","join","claim","suggested","undefined","resolution","_createdAt"],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { isHttpError } from '@sanity/client';
5
+ import { listIssues } from '../../../services/context.js';
6
+ const listIssuesDebug = subdebug('context:issues:list');
7
+ export class ListIssuesCommand extends SanityCommand {
8
+ static args = {
9
+ knowledgeBaseId: Args.string({
10
+ description: 'Knowledge base ID',
11
+ required: true
12
+ })
13
+ };
14
+ static description = 'List issues found by knowledge base builds';
15
+ static enableJsonFlag = true;
16
+ static examples = [
17
+ {
18
+ command: '<%= config.bin %> <%= command.id %> kb-abc123',
19
+ description: 'List all issues for a knowledge base'
20
+ },
21
+ {
22
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 --status open',
23
+ description: 'List issues awaiting triage'
24
+ },
25
+ {
26
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 --kind conflict --severity critical',
27
+ description: 'List critical conflicts'
28
+ },
29
+ {
30
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 --scope billing',
31
+ description: 'List issues about entries under billing/'
32
+ },
33
+ {
34
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',
35
+ description: 'Output issues as JSON'
36
+ }
37
+ ];
38
+ static flags = {
39
+ kind: Flags.custom({
40
+ description: 'Only list issues of this kind',
41
+ // A Record forces every kind the client knows to be listed, so the options can't drift
42
+ options: Object.keys({
43
+ add_entry: true,
44
+ conflict: true,
45
+ gap: true,
46
+ merge_entry: true,
47
+ remove_entry: true,
48
+ split_entry: true,
49
+ update_required: true
50
+ })
51
+ })(),
52
+ scope: Flags.string({
53
+ description: 'Only list issues about this entry path or anything under it (`*` for knowledge-base-wide issues)',
54
+ helpValue: '<path>',
55
+ parse: async (input)=>{
56
+ const trimmed = input.trim().replace(/\/+$/, '');
57
+ if (trimmed === '') {
58
+ throw new Error('`--scope` cannot be empty if provided');
59
+ }
60
+ return trimmed;
61
+ }
62
+ }),
63
+ severity: Flags.custom({
64
+ description: 'Only list issues of this severity',
65
+ options: [
66
+ 'critical',
67
+ 'suggestion'
68
+ ]
69
+ })(),
70
+ status: Flags.custom({
71
+ description: 'Only list issues with this status (rejected = dismissed, accepted = resolved or applied)',
72
+ options: [
73
+ 'open',
74
+ 'accepted',
75
+ 'rejected'
76
+ ]
77
+ })()
78
+ };
79
+ async run() {
80
+ const { knowledgeBaseId } = this.args;
81
+ const { json, kind, scope, severity, status } = this.flags;
82
+ let issues;
83
+ try {
84
+ issues = await listIssues(knowledgeBaseId, status);
85
+ } catch (error) {
86
+ listIssuesDebug('Error listing issues', error);
87
+ if (isHttpError(error) && error.statusCode === 404) {
88
+ this.error(`Knowledge base "${knowledgeBaseId}" not found`, {
89
+ exit: exitCodes.RUNTIME_ERROR
90
+ });
91
+ }
92
+ this.error(`Failed to list issues: ${getErrorMessage(error)}`, {
93
+ exit: exitCodes.RUNTIME_ERROR
94
+ });
95
+ }
96
+ // The client only filters on status; the rest are applied here
97
+ const matches = issues.filter(({ content })=>(kind === undefined || content.kind === kind) && (severity === undefined || content.severity === severity) && (scope === undefined || content.scopePath === scope || content.scopePath.startsWith(`${scope}/`)));
98
+ if (json) {
99
+ this.logJson(matches);
100
+ return;
101
+ }
102
+ if (matches.length === 0) {
103
+ this.log('No issues found');
104
+ return;
105
+ }
106
+ // Two lines per issue so long IDs never wrap: ID and metadata, then the summary cut to fit
107
+ const width = Math.max(process.stdout.columns ?? 100, 40);
108
+ const blocks = matches.map(({ _id, content, status: issueStatus })=>{
109
+ const meta = [
110
+ content.kind,
111
+ content.severity,
112
+ issueStatus,
113
+ content.scopePath
114
+ ].join(' · ');
115
+ return `${_id} ${meta}\n ${truncate(content.issue, width - 2)}`;
116
+ });
117
+ this.log(blocks.join('\n\n'));
118
+ }
119
+ }
120
+ function truncate(text, maxLength) {
121
+ // Count characters, not UTF-16 units, so an emoji at the cut point isn't split
122
+ const chars = [
123
+ ...text.replaceAll(/\s+/g, ' ').trim()
124
+ ];
125
+ return chars.length <= maxLength ? chars.join('') : `${chars.slice(0, maxLength - 1).join('')}…`;
126
+ }
127
+
128
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/issues/list.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type Context, isHttpError} from '@sanity/client'\n\nimport {listIssues} from '../../../services/context.js'\n\nconst listIssuesDebug = subdebug('context:issues:list')\n\nexport class ListIssuesCommand extends SanityCommand<typeof ListIssuesCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'List issues found by knowledge base builds'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'List all issues for a knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --status open',\n description: 'List issues awaiting triage',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --kind conflict --severity critical',\n description: 'List critical conflicts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --scope billing',\n description: 'List issues about entries under billing/',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output issues as JSON',\n },\n ]\n\n static override flags = {\n kind: Flags.custom<IssueKind>({\n description: 'Only list issues of this kind',\n // A Record forces every kind the client knows to be listed, so the options can't drift\n options: Object.keys({\n add_entry: true,\n conflict: true,\n gap: true,\n merge_entry: true,\n remove_entry: true,\n split_entry: true,\n update_required: true,\n } satisfies Record<IssueKind, true>),\n })(),\n scope: Flags.string({\n description:\n 'Only list issues about this entry path or anything under it (`*` for knowledge-base-wide issues)',\n helpValue: '<path>',\n parse: async (input: string) => {\n const trimmed = input.trim().replace(/\\/+$/, '')\n if (trimmed === '') {\n throw new Error('`--scope` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n severity: Flags.custom<Context.IssueDoc['content']['severity']>({\n description: 'Only list issues of this severity',\n options: ['critical', 'suggestion'],\n })(),\n status: Flags.custom<Context.IssueDoc['status']>({\n description:\n 'Only list issues with this status (rejected = dismissed, accepted = resolved or applied)',\n options: ['open', 'accepted', 'rejected'],\n })(),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json, kind, scope, severity, status} = this.flags\n\n let issues\n try {\n issues = await listIssues(knowledgeBaseId, status)\n } catch (error) {\n listIssuesDebug('Error listing issues', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to list issues: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // The client only filters on status; the rest are applied here\n const matches = issues.filter(\n ({content}) =>\n (kind === undefined || content.kind === kind) &&\n (severity === undefined || content.severity === severity) &&\n (scope === undefined ||\n content.scopePath === scope ||\n content.scopePath.startsWith(`${scope}/`)),\n )\n\n if (json) {\n this.logJson(matches)\n return\n }\n\n if (matches.length === 0) {\n this.log('No issues found')\n return\n }\n\n // Two lines per issue so long IDs never wrap: ID and metadata, then the summary cut to fit\n const width = Math.max(process.stdout.columns ?? 100, 40)\n const blocks = matches.map(({_id, content, status: issueStatus}) => {\n const meta = [content.kind, content.severity, issueStatus, content.scopePath].join(' · ')\n return `${_id} ${meta}\\n ${truncate(content.issue, width - 2)}`\n })\n this.log(blocks.join('\\n\\n'))\n }\n}\n\ntype IssueKind = Context.IssueDoc['content']['kind']\n\nfunction truncate(text: string, maxLength: number): string {\n // Count characters, not UTF-16 units, so an emoji at the cut point isn't split\n const chars = [...text.replaceAll(/\\s+/g, ' ').trim()]\n return chars.length <= maxLength ? chars.join('') : `${chars.slice(0, maxLength - 1).join('')}…`\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","listIssues","listIssuesDebug","ListIssuesCommand","args","knowledgeBaseId","string","description","required","enableJsonFlag","examples","command","flags","kind","custom","options","Object","keys","add_entry","conflict","gap","merge_entry","remove_entry","split_entry","update_required","scope","helpValue","parse","input","trimmed","trim","replace","Error","severity","status","run","json","issues","error","statusCode","exit","RUNTIME_ERROR","matches","filter","content","undefined","scopePath","startsWith","logJson","length","log","width","Math","max","process","stdout","columns","blocks","map","_id","issueStatus","meta","join","truncate","issue","text","maxLength","chars","replaceAll","slice"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { Args } from '@oclif/core';
2
+ import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { isHttpError } from '@sanity/client';
5
+ import { reopenIssue } from '../../../services/context.js';
6
+ const reopenIssueDebug = subdebug('context:issues:reopen');
7
+ export class ReopenIssueCommand extends SanityCommand {
8
+ static args = {
9
+ knowledgeBaseId: Args.string({
10
+ description: 'Knowledge base ID',
11
+ required: true
12
+ }),
13
+ // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
14
+ issueId: Args.string({
15
+ description: 'Issue ID',
16
+ required: true
17
+ })
18
+ };
19
+ static description = 'Reopen a resolved conflict issue';
20
+ static examples = [
21
+ {
22
+ command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',
23
+ description: 'Return a resolved conflict issue to triage'
24
+ }
25
+ ];
26
+ async run() {
27
+ const { issueId, knowledgeBaseId } = this.args;
28
+ let reopened;
29
+ try {
30
+ reopened = await reopenIssue(knowledgeBaseId, issueId);
31
+ } catch (error) {
32
+ reopenIssueDebug('Error reopening issue', error);
33
+ if (isHttpError(error) && error.statusCode === 404) {
34
+ this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
35
+ exit: exitCodes.RUNTIME_ERROR
36
+ });
37
+ }
38
+ this.error(`Failed to reopen issue: ${getErrorMessage(error)}`, {
39
+ exit: exitCodes.RUNTIME_ERROR
40
+ });
41
+ }
42
+ // The API returns the issue unchanged when it cannot be reopened
43
+ if (reopened.status !== 'open') {
44
+ const status = reopened.status === 'rejected' ? 'rejected (dismissed)' : 'accepted (resolved or applied)';
45
+ this.error(`Issue "${issueId}" is ${status} and cannot be reopened.\nOnly resolved conflict issues can be reopened.`, {
46
+ exit: exitCodes.RUNTIME_ERROR
47
+ });
48
+ }
49
+ this.log('Issue reopened');
50
+ }
51
+ }
52
+
53
+ //# sourceMappingURL=reopen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/commands/context/issues/reopen.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {reopenIssue} from '../../../services/context.js'\n\nconst reopenIssueDebug = subdebug('context:issues:reopen')\n\nexport class ReopenIssueCommand extends SanityCommand<typeof ReopenIssueCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description: 'Issue ID',\n required: true,\n }),\n }\n\n static override description = 'Reopen a resolved conflict issue'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',\n description: 'Return a resolved conflict issue to triage',\n },\n ]\n\n public async run(): Promise<void> {\n const {issueId, knowledgeBaseId} = this.args\n\n let reopened\n try {\n reopened = await reopenIssue(knowledgeBaseId, issueId)\n } catch (error) {\n reopenIssueDebug('Error reopening issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to reopen issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // The API returns the issue unchanged when it cannot be reopened\n if (reopened.status !== 'open') {\n const status =\n reopened.status === 'rejected' ? 'rejected (dismissed)' : 'accepted (resolved or applied)'\n this.error(\n `Issue \"${issueId}\" is ${status} and cannot be reopened.\\nOnly resolved conflict issues can be reopened.`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n this.log('Issue reopened')\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","reopenIssue","reopenIssueDebug","ReopenIssueCommand","args","knowledgeBaseId","string","description","required","issueId","examples","command","run","reopened","error","statusCode","exit","RUNTIME_ERROR","status","log"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,QAAO,+BAA8B;AAExD,MAAMC,mBAAmBJ,SAAS;AAElC,OAAO,MAAMK,2BAA2BN;IACtC,OAAgBO,OAAO;QACrBC,iBAAiBV,KAAKW,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,SAASd,KAAKW,MAAM,CAAC;YACnBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,mCAAkC;IAEhE,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,MAAaK,MAAqB;QAChC,MAAM,EAACH,OAAO,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAE5C,IAAIS;QACJ,IAAI;YACFA,WAAW,MAAMZ,YAAYI,iBAAiBI;QAChD,EAAE,OAAOK,OAAO;YACdZ,iBAAiB,yBAAyBY;YAC1C,IAAId,YAAYc,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,OAAO,EAAEL,QAAQ,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAChFW,MAAMpB,UAAUqB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAEf,gBAAgBe,QAAQ,EAAE;gBAC9DE,MAAMpB,UAAUqB,aAAa;YAC/B;QACF;QAEA,iEAAiE;QACjE,IAAIJ,SAASK,MAAM,KAAK,QAAQ;YAC9B,MAAMA,SACJL,SAASK,MAAM,KAAK,aAAa,yBAAyB;YAC5D,IAAI,CAACJ,KAAK,CACR,CAAC,OAAO,EAAEL,QAAQ,KAAK,EAAES,OAAO,wEAAwE,CAAC,EACzG;gBAACF,MAAMpB,UAAUqB,aAAa;YAAA;QAElC;QAEA,IAAI,CAACE,GAAG,CAAC;IACX;AACF"}