@displaydev/cli 0.17.0 → 0.19.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.
- package/dist/api-client.js +208 -32
- package/dist/main-helpers.js +13 -1
- package/dist/main.js +633 -16
- package/dist/mcp-server.js +476 -51
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -726,11 +726,24 @@ program.command('rename <shortId>').description('Rename a published artifact. Sl
|
|
|
726
726
|
})();
|
|
727
727
|
});
|
|
728
728
|
// --- find ---
|
|
729
|
-
|
|
729
|
+
function collectAuthor(value, prev) {
|
|
730
|
+
return prev.concat(value);
|
|
731
|
+
}
|
|
732
|
+
function parseVisibilityCsv(raw) {
|
|
733
|
+
return raw.split(',').map(function(v) {
|
|
734
|
+
return v.trim();
|
|
735
|
+
}).filter(Boolean);
|
|
736
|
+
}
|
|
737
|
+
var VISIBILITY_VALUES = new Set([
|
|
738
|
+
'public',
|
|
739
|
+
'company',
|
|
740
|
+
'private'
|
|
741
|
+
]);
|
|
742
|
+
program.command('find [query]').alias('list').description('List or search artifacts. Omit [query] to list every artifact (paginated).').option('--author <a>', 'Filter by author (repeatable). Each value: email, userId, or "me".', collectAuthor, []).option('--visibility <list>', 'CSV of visibility levels: public, company, private. "private" returns only your own.').option('--since <date>', 'Filter by updated since ISO date').option('--sort <col>', 'Sort column: updated_at, view_count, name').option('--dir <direction>', 'Sort direction: asc or desc').option('--cursor <token>', 'Opaque pagination token from a prior response. Drop the cursor when filters change — the wire only validates it against sort/dir, so reusing it after changing --author / --visibility / --since / [query] silently skews results.').option('--limit <n>', 'Max rows to fetch (1-100)', function(v) {
|
|
730
743
|
return parseInt(v, 10);
|
|
731
744
|
}).action(function(query, opts) {
|
|
732
745
|
return _async_to_generator(function() {
|
|
733
|
-
var
|
|
746
|
+
var visibility, tokens, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, v, auth, client, response, err, msg, data, nextCursor, totalCount, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, a;
|
|
734
747
|
return _ts_generator(this, function(_state) {
|
|
735
748
|
switch(_state.label){
|
|
736
749
|
case 0:
|
|
@@ -746,53 +759,126 @@ program.command('find [query]').description('Search for artifacts').option('--by
|
|
|
746
759
|
console.error("Invalid --dir: ".concat(opts.dir, ". Use asc or desc."));
|
|
747
760
|
process.exit(1);
|
|
748
761
|
}
|
|
762
|
+
if (opts.visibility) {
|
|
763
|
+
tokens = parseVisibilityCsv(opts.visibility);
|
|
764
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
765
|
+
try {
|
|
766
|
+
for(_iterator = tokens[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
767
|
+
v = _step.value;
|
|
768
|
+
if (!VISIBILITY_VALUES.has(v)) {
|
|
769
|
+
console.error("Invalid --visibility: ".concat(v, ". Use public, company, or private."));
|
|
770
|
+
process.exit(1);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
} catch (err) {
|
|
774
|
+
_didIteratorError = true;
|
|
775
|
+
_iteratorError = err;
|
|
776
|
+
} finally{
|
|
777
|
+
try {
|
|
778
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
779
|
+
_iterator.return();
|
|
780
|
+
}
|
|
781
|
+
} finally{
|
|
782
|
+
if (_didIteratorError) {
|
|
783
|
+
throw _iteratorError;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
visibility = tokens;
|
|
788
|
+
}
|
|
749
789
|
return [
|
|
750
790
|
4,
|
|
751
791
|
resolveAuthOrConfig()
|
|
752
792
|
];
|
|
753
793
|
case 1:
|
|
754
794
|
auth = _state.sent();
|
|
795
|
+
// The wire silently drops `me` when authenticated with an org API key (no
|
|
796
|
+
// session user → caller id is null in resolveAuthorIds). Catch that at the
|
|
797
|
+
// command layer so the user gets an explicit failure rather than an
|
|
798
|
+
// unfiltered list. Trim each value to mirror the wire — it trims tokens
|
|
799
|
+
// before resolving `me`, so `--author ' me '` would otherwise bypass the
|
|
800
|
+
// guard and re-introduce the silent-broaden bug.
|
|
801
|
+
if (auth.keyType === 'org' && opts.author.some(function(a) {
|
|
802
|
+
return a.trim() === 'me';
|
|
803
|
+
})) {
|
|
804
|
+
console.error('--author me requires a user-scoped credential. Use a user API key or sign in via dashboard.');
|
|
805
|
+
process.exit(1);
|
|
806
|
+
}
|
|
755
807
|
client = createClient(auth);
|
|
808
|
+
_state.label = 2;
|
|
809
|
+
case 2:
|
|
810
|
+
_state.trys.push([
|
|
811
|
+
2,
|
|
812
|
+
4,
|
|
813
|
+
,
|
|
814
|
+
5
|
|
815
|
+
]);
|
|
756
816
|
return [
|
|
757
817
|
4,
|
|
758
818
|
client.find({
|
|
759
819
|
query: query,
|
|
760
|
-
|
|
761
|
-
|
|
820
|
+
author: opts.author.length > 0 ? opts.author : undefined,
|
|
821
|
+
visibility: visibility,
|
|
762
822
|
since: opts.since,
|
|
763
823
|
sort: opts.sort,
|
|
764
824
|
dir: opts.dir,
|
|
825
|
+
cursor: opts.cursor,
|
|
765
826
|
limit: opts.limit
|
|
766
827
|
})
|
|
767
828
|
];
|
|
768
|
-
case
|
|
769
|
-
|
|
770
|
-
|
|
829
|
+
case 3:
|
|
830
|
+
response = _state.sent();
|
|
831
|
+
return [
|
|
832
|
+
3,
|
|
833
|
+
5
|
|
834
|
+
];
|
|
835
|
+
case 4:
|
|
836
|
+
err = _state.sent();
|
|
837
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
838
|
+
console.error(msg);
|
|
839
|
+
process.exit(1);
|
|
840
|
+
return [
|
|
841
|
+
3,
|
|
842
|
+
5
|
|
843
|
+
];
|
|
844
|
+
case 5:
|
|
845
|
+
data = response.data, nextCursor = response.nextCursor, totalCount = response.totalCount;
|
|
846
|
+
if (data.length === 0) {
|
|
771
847
|
console.log('No artifacts found.');
|
|
772
848
|
return [
|
|
773
849
|
2
|
|
774
850
|
];
|
|
775
851
|
}
|
|
776
|
-
|
|
852
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
777
853
|
try {
|
|
778
|
-
for(
|
|
779
|
-
a =
|
|
854
|
+
for(_iterator1 = data[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
855
|
+
a = _step1.value;
|
|
780
856
|
console.log("".concat(a.shortId, " v").concat(a.currentVersion, " ").concat(a.name, " ").concat(a.url));
|
|
781
857
|
}
|
|
782
858
|
} catch (err) {
|
|
783
|
-
|
|
784
|
-
|
|
859
|
+
_didIteratorError1 = true;
|
|
860
|
+
_iteratorError1 = err;
|
|
785
861
|
} finally{
|
|
786
862
|
try {
|
|
787
|
-
if (!
|
|
788
|
-
|
|
863
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
864
|
+
_iterator1.return();
|
|
789
865
|
}
|
|
790
866
|
} finally{
|
|
791
|
-
if (
|
|
792
|
-
throw
|
|
867
|
+
if (_didIteratorError1) {
|
|
868
|
+
throw _iteratorError1;
|
|
793
869
|
}
|
|
794
870
|
}
|
|
795
871
|
}
|
|
872
|
+
// Footer on stderr so pipe consumers (`dsp find | xargs ...`) get clean
|
|
873
|
+
// stdout. Order: count line first, then the next-page hint.
|
|
874
|
+
if (totalCount === -1) {
|
|
875
|
+
process.stderr.write("Showing ".concat(data.length, " matching artifacts (count exceeded the budget; rerun with a tighter filter to get an exact total).\n"));
|
|
876
|
+
} else if (totalCount >= 0) {
|
|
877
|
+
process.stderr.write("Showing ".concat(data.length, "/").concat(totalCount, " matching artifacts.\n"));
|
|
878
|
+
}
|
|
879
|
+
if (nextCursor !== null) {
|
|
880
|
+
process.stderr.write("More results available. Re-run with --cursor ".concat(nextCursor, " to fetch the next page.\n"));
|
|
881
|
+
}
|
|
796
882
|
return [
|
|
797
883
|
2
|
|
798
884
|
];
|
|
@@ -1617,6 +1703,537 @@ program.command('clear-logo').description('Remove the org logo (idempotent — s
|
|
|
1617
1703
|
});
|
|
1618
1704
|
})();
|
|
1619
1705
|
});
|
|
1706
|
+
// --- comment add ---
|
|
1707
|
+
// `dsp comment add --artifact <shortId> --body "..." --anchor-json '<json>' [--parent <id>]`
|
|
1708
|
+
// Spec §3 maps to POST /v1/artifacts/:shortId/comments. Root posts
|
|
1709
|
+
// require a full anchor descriptor (textQuote prefix + exact + suffix
|
|
1710
|
+
// plus cssPath); replies inherit the root's anchor and must omit it.
|
|
1711
|
+
//
|
|
1712
|
+
// `--anchor-json` is intentionally the only anchor input. A bare-text
|
|
1713
|
+
// shortcut would have to fabricate prefix/suffix/cssPath, and the
|
|
1714
|
+
// underlying `dom-anchor-text-quote` resolver binds to the FIRST exact
|
|
1715
|
+
// match in the scope. Without prefix/suffix the resolver cannot
|
|
1716
|
+
// disambiguate duplicates and the comment can silently attach to the
|
|
1717
|
+
// wrong occurrence — see widget's anchor algorithm at
|
|
1718
|
+
// webapp/src/components/comments/anchor.ts:54. Forcing the caller to
|
|
1719
|
+
// supply the full descriptor (the agent has the source content; humans
|
|
1720
|
+
// can copy from the widget's selection JSON) keeps the bind reliable.
|
|
1721
|
+
program.command('comment').description('Comment-related subcommands. Run `dsp comment <cmd> --help` for each.').command('add').description('Post a root comment or reply on an artifact.').option('--artifact <shortId>', 'Artifact shortId (subject_type=artifact)').option('--kb-page <kbName...>', 'KB-page subject — pass two values: kb name then file path (subject_type=kb_page; not yet supported). Variadic (commander) — anything after `--kb-page` up to the next flag is consumed as the (kbName, filePath) tuple.').requiredOption('--body <text>', 'Comment body (≤10k chars)').option('--anchor-json <json>', 'Full anchor object as JSON: {"textQuote":{"prefix":"","exact":"...","suffix":""},"cssPath":"..."}. Required for root posts; omit for replies.').option('--parent <commentId>', 'Reply to this root comment id; omit for a root post').action(function(opts) {
|
|
1722
|
+
return _async_to_generator(function() {
|
|
1723
|
+
var subject, anchor, auth, client, result, err;
|
|
1724
|
+
return _ts_generator(this, function(_state) {
|
|
1725
|
+
switch(_state.label){
|
|
1726
|
+
case 0:
|
|
1727
|
+
subject = resolveSubjectFlags(opts);
|
|
1728
|
+
if (subject.kind === 'invalid') {
|
|
1729
|
+
console.error(subject.error);
|
|
1730
|
+
process.exit(1);
|
|
1731
|
+
}
|
|
1732
|
+
if (subject.kind === 'kb_page') {
|
|
1733
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
1734
|
+
process.exit(1);
|
|
1735
|
+
}
|
|
1736
|
+
if (!opts.parent && !opts.anchorJson) {
|
|
1737
|
+
console.error('Root comments require --anchor-json. Use --parent <commentId> for a reply.');
|
|
1738
|
+
process.exit(1);
|
|
1739
|
+
}
|
|
1740
|
+
if (opts.parent && opts.anchorJson) {
|
|
1741
|
+
console.error('Replies inherit the root anchor — omit --anchor-json when --parent is set.');
|
|
1742
|
+
process.exit(1);
|
|
1743
|
+
}
|
|
1744
|
+
if (opts.anchorJson) {
|
|
1745
|
+
try {
|
|
1746
|
+
anchor = JSON.parse(opts.anchorJson);
|
|
1747
|
+
} catch (unused) {
|
|
1748
|
+
console.error('--anchor-json is not valid JSON.');
|
|
1749
|
+
process.exit(1);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
return [
|
|
1753
|
+
4,
|
|
1754
|
+
resolveAuthOrConfig()
|
|
1755
|
+
];
|
|
1756
|
+
case 1:
|
|
1757
|
+
auth = _state.sent();
|
|
1758
|
+
client = createClient(auth);
|
|
1759
|
+
_state.label = 2;
|
|
1760
|
+
case 2:
|
|
1761
|
+
_state.trys.push([
|
|
1762
|
+
2,
|
|
1763
|
+
4,
|
|
1764
|
+
,
|
|
1765
|
+
5
|
|
1766
|
+
]);
|
|
1767
|
+
return [
|
|
1768
|
+
4,
|
|
1769
|
+
client.addComment(subject.shortId, {
|
|
1770
|
+
body: opts.body,
|
|
1771
|
+
anchor: anchor,
|
|
1772
|
+
parentId: opts.parent
|
|
1773
|
+
})
|
|
1774
|
+
];
|
|
1775
|
+
case 3:
|
|
1776
|
+
result = _state.sent();
|
|
1777
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1778
|
+
return [
|
|
1779
|
+
3,
|
|
1780
|
+
5
|
|
1781
|
+
];
|
|
1782
|
+
case 4:
|
|
1783
|
+
err = _state.sent();
|
|
1784
|
+
handleCommentApiError(err);
|
|
1785
|
+
return [
|
|
1786
|
+
3,
|
|
1787
|
+
5
|
|
1788
|
+
];
|
|
1789
|
+
case 5:
|
|
1790
|
+
return [
|
|
1791
|
+
2
|
|
1792
|
+
];
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
})();
|
|
1796
|
+
});
|
|
1797
|
+
// --- comment list ---
|
|
1798
|
+
program.commands.find(function(c) {
|
|
1799
|
+
return c.name() === 'comment';
|
|
1800
|
+
}).command('list').description('List comment threads on a subject.').option('--artifact <shortId>', 'Artifact shortId (subject_type=artifact)').option('--kb-page <kbName...>', 'KB-page subject — pass two values: kb name then file path (subject_type=kb_page; not yet supported). Variadic (commander) — anything after `--kb-page` up to the next flag is consumed as the (kbName, filePath) tuple.').option('--status <state>', 'open | resolved | all (default: open)').option('--since <iso>', 'ISO-8601 timestamp — filter to threads with activity at or after this point').action(function(opts) {
|
|
1801
|
+
return _async_to_generator(function() {
|
|
1802
|
+
var subject, auth, client, result, err;
|
|
1803
|
+
return _ts_generator(this, function(_state) {
|
|
1804
|
+
switch(_state.label){
|
|
1805
|
+
case 0:
|
|
1806
|
+
subject = resolveSubjectFlags(opts);
|
|
1807
|
+
if (subject.kind === 'invalid') {
|
|
1808
|
+
console.error(subject.error);
|
|
1809
|
+
process.exit(1);
|
|
1810
|
+
}
|
|
1811
|
+
if (subject.kind === 'kb_page') {
|
|
1812
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
1813
|
+
process.exit(1);
|
|
1814
|
+
}
|
|
1815
|
+
if (opts.status && ![
|
|
1816
|
+
'open',
|
|
1817
|
+
'resolved',
|
|
1818
|
+
'all'
|
|
1819
|
+
].includes(opts.status)) {
|
|
1820
|
+
console.error("Invalid --status: ".concat(opts.status, ". Use open, resolved, or all."));
|
|
1821
|
+
process.exit(1);
|
|
1822
|
+
}
|
|
1823
|
+
return [
|
|
1824
|
+
4,
|
|
1825
|
+
resolveAuthOrConfig()
|
|
1826
|
+
];
|
|
1827
|
+
case 1:
|
|
1828
|
+
auth = _state.sent();
|
|
1829
|
+
client = createClient(auth);
|
|
1830
|
+
_state.label = 2;
|
|
1831
|
+
case 2:
|
|
1832
|
+
_state.trys.push([
|
|
1833
|
+
2,
|
|
1834
|
+
4,
|
|
1835
|
+
,
|
|
1836
|
+
5
|
|
1837
|
+
]);
|
|
1838
|
+
return [
|
|
1839
|
+
4,
|
|
1840
|
+
client.listComments(subject.shortId, {
|
|
1841
|
+
status: opts.status,
|
|
1842
|
+
since: opts.since
|
|
1843
|
+
})
|
|
1844
|
+
];
|
|
1845
|
+
case 3:
|
|
1846
|
+
result = _state.sent();
|
|
1847
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1848
|
+
return [
|
|
1849
|
+
3,
|
|
1850
|
+
5
|
|
1851
|
+
];
|
|
1852
|
+
case 4:
|
|
1853
|
+
err = _state.sent();
|
|
1854
|
+
handleCommentApiError(err);
|
|
1855
|
+
return [
|
|
1856
|
+
3,
|
|
1857
|
+
5
|
|
1858
|
+
];
|
|
1859
|
+
case 5:
|
|
1860
|
+
return [
|
|
1861
|
+
2
|
|
1862
|
+
];
|
|
1863
|
+
}
|
|
1864
|
+
});
|
|
1865
|
+
})();
|
|
1866
|
+
});
|
|
1867
|
+
// --- comment edit ---
|
|
1868
|
+
program.commands.find(function(c) {
|
|
1869
|
+
return c.name() === 'comment';
|
|
1870
|
+
}).command('edit <commentId>').description('Edit your own comment within the 5-minute author window.').requiredOption('--body <text>', 'New comment body').action(function(commentId, opts) {
|
|
1871
|
+
return _async_to_generator(function() {
|
|
1872
|
+
var auth, client, result, err;
|
|
1873
|
+
return _ts_generator(this, function(_state) {
|
|
1874
|
+
switch(_state.label){
|
|
1875
|
+
case 0:
|
|
1876
|
+
return [
|
|
1877
|
+
4,
|
|
1878
|
+
resolveAuthOrConfig()
|
|
1879
|
+
];
|
|
1880
|
+
case 1:
|
|
1881
|
+
auth = _state.sent();
|
|
1882
|
+
client = createClient(auth);
|
|
1883
|
+
_state.label = 2;
|
|
1884
|
+
case 2:
|
|
1885
|
+
_state.trys.push([
|
|
1886
|
+
2,
|
|
1887
|
+
4,
|
|
1888
|
+
,
|
|
1889
|
+
5
|
|
1890
|
+
]);
|
|
1891
|
+
return [
|
|
1892
|
+
4,
|
|
1893
|
+
client.editComment(commentId, opts.body)
|
|
1894
|
+
];
|
|
1895
|
+
case 3:
|
|
1896
|
+
result = _state.sent();
|
|
1897
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1898
|
+
return [
|
|
1899
|
+
3,
|
|
1900
|
+
5
|
|
1901
|
+
];
|
|
1902
|
+
case 4:
|
|
1903
|
+
err = _state.sent();
|
|
1904
|
+
handleCommentApiError(err);
|
|
1905
|
+
return [
|
|
1906
|
+
3,
|
|
1907
|
+
5
|
|
1908
|
+
];
|
|
1909
|
+
case 5:
|
|
1910
|
+
return [
|
|
1911
|
+
2
|
|
1912
|
+
];
|
|
1913
|
+
}
|
|
1914
|
+
});
|
|
1915
|
+
})();
|
|
1916
|
+
});
|
|
1917
|
+
// --- comment delete ---
|
|
1918
|
+
program.commands.find(function(c) {
|
|
1919
|
+
return c.name() === 'comment';
|
|
1920
|
+
}).command('delete <commentId>').description('Soft-delete a comment. Author / artifact creator / org admin.').action(function(commentId) {
|
|
1921
|
+
return _async_to_generator(function() {
|
|
1922
|
+
var auth, client, err;
|
|
1923
|
+
return _ts_generator(this, function(_state) {
|
|
1924
|
+
switch(_state.label){
|
|
1925
|
+
case 0:
|
|
1926
|
+
return [
|
|
1927
|
+
4,
|
|
1928
|
+
resolveAuthOrConfig()
|
|
1929
|
+
];
|
|
1930
|
+
case 1:
|
|
1931
|
+
auth = _state.sent();
|
|
1932
|
+
client = createClient(auth);
|
|
1933
|
+
_state.label = 2;
|
|
1934
|
+
case 2:
|
|
1935
|
+
_state.trys.push([
|
|
1936
|
+
2,
|
|
1937
|
+
4,
|
|
1938
|
+
,
|
|
1939
|
+
5
|
|
1940
|
+
]);
|
|
1941
|
+
return [
|
|
1942
|
+
4,
|
|
1943
|
+
client.deleteComment(commentId)
|
|
1944
|
+
];
|
|
1945
|
+
case 3:
|
|
1946
|
+
_state.sent();
|
|
1947
|
+
console.log('Comment deleted.');
|
|
1948
|
+
return [
|
|
1949
|
+
3,
|
|
1950
|
+
5
|
|
1951
|
+
];
|
|
1952
|
+
case 4:
|
|
1953
|
+
err = _state.sent();
|
|
1954
|
+
handleCommentApiError(err);
|
|
1955
|
+
return [
|
|
1956
|
+
3,
|
|
1957
|
+
5
|
|
1958
|
+
];
|
|
1959
|
+
case 5:
|
|
1960
|
+
return [
|
|
1961
|
+
2
|
|
1962
|
+
];
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1965
|
+
})();
|
|
1966
|
+
});
|
|
1967
|
+
// --- thread resolve / reopen ---
|
|
1968
|
+
var threadCmd = program.command('thread').description('Thread-level operations (resolve, reopen).');
|
|
1969
|
+
threadCmd.command('resolve <rootCommentId>').description('Mark a thread resolved. Thread participant / artifact creator / org admin.').action(function(commentId) {
|
|
1970
|
+
return _async_to_generator(function() {
|
|
1971
|
+
var auth, client, result, err;
|
|
1972
|
+
return _ts_generator(this, function(_state) {
|
|
1973
|
+
switch(_state.label){
|
|
1974
|
+
case 0:
|
|
1975
|
+
return [
|
|
1976
|
+
4,
|
|
1977
|
+
resolveAuthOrConfig()
|
|
1978
|
+
];
|
|
1979
|
+
case 1:
|
|
1980
|
+
auth = _state.sent();
|
|
1981
|
+
client = createClient(auth);
|
|
1982
|
+
_state.label = 2;
|
|
1983
|
+
case 2:
|
|
1984
|
+
_state.trys.push([
|
|
1985
|
+
2,
|
|
1986
|
+
4,
|
|
1987
|
+
,
|
|
1988
|
+
5
|
|
1989
|
+
]);
|
|
1990
|
+
return [
|
|
1991
|
+
4,
|
|
1992
|
+
client.resolveThread(commentId)
|
|
1993
|
+
];
|
|
1994
|
+
case 3:
|
|
1995
|
+
result = _state.sent();
|
|
1996
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1997
|
+
return [
|
|
1998
|
+
3,
|
|
1999
|
+
5
|
|
2000
|
+
];
|
|
2001
|
+
case 4:
|
|
2002
|
+
err = _state.sent();
|
|
2003
|
+
handleCommentApiError(err);
|
|
2004
|
+
return [
|
|
2005
|
+
3,
|
|
2006
|
+
5
|
|
2007
|
+
];
|
|
2008
|
+
case 5:
|
|
2009
|
+
return [
|
|
2010
|
+
2
|
|
2011
|
+
];
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
})();
|
|
2015
|
+
});
|
|
2016
|
+
threadCmd.command('reopen <rootCommentId>').description('Reopen a resolved thread. Any authenticated user with view access.').action(function(commentId) {
|
|
2017
|
+
return _async_to_generator(function() {
|
|
2018
|
+
var auth, client, result, err;
|
|
2019
|
+
return _ts_generator(this, function(_state) {
|
|
2020
|
+
switch(_state.label){
|
|
2021
|
+
case 0:
|
|
2022
|
+
return [
|
|
2023
|
+
4,
|
|
2024
|
+
resolveAuthOrConfig()
|
|
2025
|
+
];
|
|
2026
|
+
case 1:
|
|
2027
|
+
auth = _state.sent();
|
|
2028
|
+
client = createClient(auth);
|
|
2029
|
+
_state.label = 2;
|
|
2030
|
+
case 2:
|
|
2031
|
+
_state.trys.push([
|
|
2032
|
+
2,
|
|
2033
|
+
4,
|
|
2034
|
+
,
|
|
2035
|
+
5
|
|
2036
|
+
]);
|
|
2037
|
+
return [
|
|
2038
|
+
4,
|
|
2039
|
+
client.reopenThread(commentId)
|
|
2040
|
+
];
|
|
2041
|
+
case 3:
|
|
2042
|
+
result = _state.sent();
|
|
2043
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2044
|
+
return [
|
|
2045
|
+
3,
|
|
2046
|
+
5
|
|
2047
|
+
];
|
|
2048
|
+
case 4:
|
|
2049
|
+
err = _state.sent();
|
|
2050
|
+
handleCommentApiError(err);
|
|
2051
|
+
return [
|
|
2052
|
+
3,
|
|
2053
|
+
5
|
|
2054
|
+
];
|
|
2055
|
+
case 5:
|
|
2056
|
+
return [
|
|
2057
|
+
2
|
|
2058
|
+
];
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
2061
|
+
})();
|
|
2062
|
+
});
|
|
2063
|
+
// --- watch / unwatch ---
|
|
2064
|
+
program.command('watch').description('Watch a subject for comment notifications.').option('--artifact <shortId>', 'Artifact shortId (subject_type=artifact)').option('--kb-page <kbName...>', 'KB-page subject — pass two values: kb name then file path (subject_type=kb_page; not yet supported). Variadic (commander) — anything after `--kb-page` up to the next flag is consumed as the (kbName, filePath) tuple.').action(function(opts) {
|
|
2065
|
+
return _async_to_generator(function() {
|
|
2066
|
+
var subject, auth, client, result, err;
|
|
2067
|
+
return _ts_generator(this, function(_state) {
|
|
2068
|
+
switch(_state.label){
|
|
2069
|
+
case 0:
|
|
2070
|
+
subject = resolveSubjectFlags(opts);
|
|
2071
|
+
if (subject.kind === 'invalid') {
|
|
2072
|
+
console.error(subject.error);
|
|
2073
|
+
process.exit(1);
|
|
2074
|
+
}
|
|
2075
|
+
if (subject.kind === 'kb_page') {
|
|
2076
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
2077
|
+
process.exit(1);
|
|
2078
|
+
}
|
|
2079
|
+
return [
|
|
2080
|
+
4,
|
|
2081
|
+
resolveAuthOrConfig()
|
|
2082
|
+
];
|
|
2083
|
+
case 1:
|
|
2084
|
+
auth = _state.sent();
|
|
2085
|
+
client = createClient(auth);
|
|
2086
|
+
_state.label = 2;
|
|
2087
|
+
case 2:
|
|
2088
|
+
_state.trys.push([
|
|
2089
|
+
2,
|
|
2090
|
+
4,
|
|
2091
|
+
,
|
|
2092
|
+
5
|
|
2093
|
+
]);
|
|
2094
|
+
return [
|
|
2095
|
+
4,
|
|
2096
|
+
client.watchArtifact(subject.shortId)
|
|
2097
|
+
];
|
|
2098
|
+
case 3:
|
|
2099
|
+
result = _state.sent();
|
|
2100
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2101
|
+
return [
|
|
2102
|
+
3,
|
|
2103
|
+
5
|
|
2104
|
+
];
|
|
2105
|
+
case 4:
|
|
2106
|
+
err = _state.sent();
|
|
2107
|
+
handleCommentApiError(err);
|
|
2108
|
+
return [
|
|
2109
|
+
3,
|
|
2110
|
+
5
|
|
2111
|
+
];
|
|
2112
|
+
case 5:
|
|
2113
|
+
return [
|
|
2114
|
+
2
|
|
2115
|
+
];
|
|
2116
|
+
}
|
|
2117
|
+
});
|
|
2118
|
+
})();
|
|
2119
|
+
});
|
|
2120
|
+
program.command('unwatch').description('Unwatch a subject.').option('--artifact <shortId>', 'Artifact shortId (subject_type=artifact)').option('--kb-page <kbName...>', 'KB-page subject — pass two values: kb name then file path (subject_type=kb_page; not yet supported). Variadic (commander) — anything after `--kb-page` up to the next flag is consumed as the (kbName, filePath) tuple.').action(function(opts) {
|
|
2121
|
+
return _async_to_generator(function() {
|
|
2122
|
+
var subject, auth, client, err;
|
|
2123
|
+
return _ts_generator(this, function(_state) {
|
|
2124
|
+
switch(_state.label){
|
|
2125
|
+
case 0:
|
|
2126
|
+
subject = resolveSubjectFlags(opts);
|
|
2127
|
+
if (subject.kind === 'invalid') {
|
|
2128
|
+
console.error(subject.error);
|
|
2129
|
+
process.exit(1);
|
|
2130
|
+
}
|
|
2131
|
+
if (subject.kind === 'kb_page') {
|
|
2132
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
2133
|
+
process.exit(1);
|
|
2134
|
+
}
|
|
2135
|
+
return [
|
|
2136
|
+
4,
|
|
2137
|
+
resolveAuthOrConfig()
|
|
2138
|
+
];
|
|
2139
|
+
case 1:
|
|
2140
|
+
auth = _state.sent();
|
|
2141
|
+
client = createClient(auth);
|
|
2142
|
+
_state.label = 2;
|
|
2143
|
+
case 2:
|
|
2144
|
+
_state.trys.push([
|
|
2145
|
+
2,
|
|
2146
|
+
4,
|
|
2147
|
+
,
|
|
2148
|
+
5
|
|
2149
|
+
]);
|
|
2150
|
+
return [
|
|
2151
|
+
4,
|
|
2152
|
+
client.unwatchArtifact(subject.shortId)
|
|
2153
|
+
];
|
|
2154
|
+
case 3:
|
|
2155
|
+
_state.sent();
|
|
2156
|
+
console.log('Unwatched.');
|
|
2157
|
+
return [
|
|
2158
|
+
3,
|
|
2159
|
+
5
|
|
2160
|
+
];
|
|
2161
|
+
case 4:
|
|
2162
|
+
err = _state.sent();
|
|
2163
|
+
handleCommentApiError(err);
|
|
2164
|
+
return [
|
|
2165
|
+
3,
|
|
2166
|
+
5
|
|
2167
|
+
];
|
|
2168
|
+
case 5:
|
|
2169
|
+
return [
|
|
2170
|
+
2
|
|
2171
|
+
];
|
|
2172
|
+
}
|
|
2173
|
+
});
|
|
2174
|
+
})();
|
|
2175
|
+
});
|
|
2176
|
+
function resolveSubjectFlags(opts) {
|
|
2177
|
+
var hasArtifact = Boolean(opts.artifact);
|
|
2178
|
+
var kbPage = opts.kbPage;
|
|
2179
|
+
var hasKbPage = Array.isArray(kbPage) && kbPage.length > 0;
|
|
2180
|
+
if (hasArtifact && hasKbPage) {
|
|
2181
|
+
return {
|
|
2182
|
+
kind: 'invalid',
|
|
2183
|
+
error: 'Pass either --artifact or --kb-page, not both.'
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
if (!hasArtifact && !hasKbPage) {
|
|
2187
|
+
return {
|
|
2188
|
+
kind: 'invalid',
|
|
2189
|
+
error: 'Pass --artifact <shortId> or --kb-page <kbName> <filePath>.'
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
if (hasArtifact) {
|
|
2193
|
+
return {
|
|
2194
|
+
kind: 'artifact',
|
|
2195
|
+
shortId: opts.artifact
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
if (kbPage.length !== 2) {
|
|
2199
|
+
return {
|
|
2200
|
+
kind: 'invalid',
|
|
2201
|
+
error: '--kb-page requires exactly two values: <kbName> <filePath>.'
|
|
2202
|
+
};
|
|
2203
|
+
}
|
|
2204
|
+
return {
|
|
2205
|
+
kind: 'kb_page',
|
|
2206
|
+
kbName: kbPage[0],
|
|
2207
|
+
filePath: kbPage[1],
|
|
2208
|
+
shortId: ''
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Common error mapper for the comment / watch / thread subcommands.
|
|
2213
|
+
* Mirrors the ApiError handling on share/rename so 401 prompts a
|
|
2214
|
+
* re-login, 403 surfaces the API's reason verbatim, 404 shows a
|
|
2215
|
+
* concrete "not found", and 410 (signed-token failures from the
|
|
2216
|
+
* email-link routes) prints the API's message. Other errors fall
|
|
2217
|
+
* through to a generic stringify.
|
|
2218
|
+
*/ function handleCommentApiError(err) {
|
|
2219
|
+
if (_instanceof(err, ApiError)) {
|
|
2220
|
+
if (err.status === 401) {
|
|
2221
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
2222
|
+
process.exit(1);
|
|
2223
|
+
}
|
|
2224
|
+
if (err.status === 404) {
|
|
2225
|
+
console.error(err.message);
|
|
2226
|
+
process.exit(4);
|
|
2227
|
+
}
|
|
2228
|
+
if (err.status === 403 || err.status === 400 || err.status === 410 || err.status === 429) {
|
|
2229
|
+
console.error(err.message);
|
|
2230
|
+
process.exit(1);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
var msg = _instanceof(err, Error) ? err.message : String(err);
|
|
2234
|
+
console.error(msg);
|
|
2235
|
+
process.exit(1);
|
|
2236
|
+
}
|
|
1620
2237
|
// --- mcp ---
|
|
1621
2238
|
program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
|
|
1622
2239
|
return _async_to_generator(function() {
|