@displaydev/cli 0.18.0 → 0.20.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 +197 -27
- package/dist/main.js +559 -5
- package/dist/mcp-server.js +517 -22
- package/dist/update-notice.js +488 -0
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -198,9 +198,26 @@ import { Command } from 'commander';
|
|
|
198
198
|
import { ApiClient, ApiError } from './api-client.js';
|
|
199
199
|
import { loadConfig, saveConfig } from './config.js';
|
|
200
200
|
import { startMcpServer } from './mcp-server.js';
|
|
201
|
+
import { emitOnExit, setCurrentVersion, setMcpMode } from './update-notice.js';
|
|
201
202
|
import { DEFAULT_API_URL, DeviceCodeDeniedError, DeviceCodeExpiredError, DeviceCodeFailedError, InvalidFlagError, PublishArgsError, classifyBrandingError, parseShortIdAndVersion, parseShowBrandingFlag, pollDeviceToken, readApiKeyFromTty, readStreamToString, resolveAuth as resolveAuthFromEnvAndConfig, validatePublishArgs } from './main-helpers.js';
|
|
202
203
|
var require = createRequire(import.meta.url);
|
|
203
204
|
var version = require('../package.json').version;
|
|
205
|
+
// Update-notice scaffolding (spec/feat-cli-update-notification.md). The
|
|
206
|
+
// `'exit'` hook fires on every termination path — natural completion,
|
|
207
|
+
// `process.exit(N)`, uncaught throws — so the notice lands regardless of
|
|
208
|
+
// which exit path the command took. `'beforeExit'` would not work; it
|
|
209
|
+
// does not fire when `process.exit()` is called explicitly.
|
|
210
|
+
//
|
|
211
|
+
// Process-level idempotency: keyed on a Symbol.for so `vi.resetModules()`
|
|
212
|
+
// + dynamic re-import in tests does not stack a second listener (each
|
|
213
|
+
// re-import would otherwise re-run this top-level statement).
|
|
214
|
+
setCurrentVersion(version);
|
|
215
|
+
var EXIT_HOOK_FLAG = Symbol.for('@displaydev/cli.exit-hook-registered');
|
|
216
|
+
var flagged = process;
|
|
217
|
+
if (!flagged[EXIT_HOOK_FLAG]) {
|
|
218
|
+
flagged[EXIT_HOOK_FLAG] = true;
|
|
219
|
+
process.on('exit', emitOnExit);
|
|
220
|
+
}
|
|
204
221
|
function resolveAuthOrConfig() {
|
|
205
222
|
return _async_to_generator(function() {
|
|
206
223
|
var auth;
|
|
@@ -260,7 +277,8 @@ function createClient(auth) {
|
|
|
260
277
|
return new ApiClient({
|
|
261
278
|
baseUrl: auth.apiUrl,
|
|
262
279
|
apiKey: auth.apiKey,
|
|
263
|
-
clientType: 'cli'
|
|
280
|
+
clientType: 'cli',
|
|
281
|
+
version: version
|
|
264
282
|
});
|
|
265
283
|
}
|
|
266
284
|
var program = new Command().name('dsp').description('display.dev CLI — publish artifacts behind company auth').version(version);
|
|
@@ -407,7 +425,8 @@ program.command('publish <path>').description('Publish an HTML or Markdown file.
|
|
|
407
425
|
publicClient = new ApiClient({
|
|
408
426
|
baseUrl: resolvePublicApiUrl(),
|
|
409
427
|
apiKey: '',
|
|
410
|
-
clientType: 'cli'
|
|
428
|
+
clientType: 'cli',
|
|
429
|
+
version: version
|
|
411
430
|
});
|
|
412
431
|
_state.label = 10;
|
|
413
432
|
case 10:
|
|
@@ -1074,7 +1093,8 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
1074
1093
|
client = new ApiClient({
|
|
1075
1094
|
baseUrl: apiUrl,
|
|
1076
1095
|
apiKey: '',
|
|
1077
|
-
clientType: 'cli'
|
|
1096
|
+
clientType: 'cli',
|
|
1097
|
+
version: version
|
|
1078
1098
|
});
|
|
1079
1099
|
if (!(opts.apiKey !== undefined)) return [
|
|
1080
1100
|
3,
|
|
@@ -1703,6 +1723,537 @@ program.command('clear-logo').description('Remove the org logo (idempotent — s
|
|
|
1703
1723
|
});
|
|
1704
1724
|
})();
|
|
1705
1725
|
});
|
|
1726
|
+
// --- comment add ---
|
|
1727
|
+
// `dsp comment add --artifact <shortId> --body "..." --anchor-json '<json>' [--parent <id>]`
|
|
1728
|
+
// Spec §3 maps to POST /v1/artifacts/:shortId/comments. Root posts
|
|
1729
|
+
// require a full anchor descriptor (textQuote prefix + exact + suffix
|
|
1730
|
+
// plus cssPath); replies inherit the root's anchor and must omit it.
|
|
1731
|
+
//
|
|
1732
|
+
// `--anchor-json` is intentionally the only anchor input. A bare-text
|
|
1733
|
+
// shortcut would have to fabricate prefix/suffix/cssPath, and the
|
|
1734
|
+
// underlying `dom-anchor-text-quote` resolver binds to the FIRST exact
|
|
1735
|
+
// match in the scope. Without prefix/suffix the resolver cannot
|
|
1736
|
+
// disambiguate duplicates and the comment can silently attach to the
|
|
1737
|
+
// wrong occurrence — see widget's anchor algorithm at
|
|
1738
|
+
// webapp/src/components/comments/anchor.ts:54. Forcing the caller to
|
|
1739
|
+
// supply the full descriptor (the agent has the source content; humans
|
|
1740
|
+
// can copy from the widget's selection JSON) keeps the bind reliable.
|
|
1741
|
+
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) {
|
|
1742
|
+
return _async_to_generator(function() {
|
|
1743
|
+
var subject, anchor, auth, client, result, err;
|
|
1744
|
+
return _ts_generator(this, function(_state) {
|
|
1745
|
+
switch(_state.label){
|
|
1746
|
+
case 0:
|
|
1747
|
+
subject = resolveSubjectFlags(opts);
|
|
1748
|
+
if (subject.kind === 'invalid') {
|
|
1749
|
+
console.error(subject.error);
|
|
1750
|
+
process.exit(1);
|
|
1751
|
+
}
|
|
1752
|
+
if (subject.kind === 'kb_page') {
|
|
1753
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
1754
|
+
process.exit(1);
|
|
1755
|
+
}
|
|
1756
|
+
if (!opts.parent && !opts.anchorJson) {
|
|
1757
|
+
console.error('Root comments require --anchor-json. Use --parent <commentId> for a reply.');
|
|
1758
|
+
process.exit(1);
|
|
1759
|
+
}
|
|
1760
|
+
if (opts.parent && opts.anchorJson) {
|
|
1761
|
+
console.error('Replies inherit the root anchor — omit --anchor-json when --parent is set.');
|
|
1762
|
+
process.exit(1);
|
|
1763
|
+
}
|
|
1764
|
+
if (opts.anchorJson) {
|
|
1765
|
+
try {
|
|
1766
|
+
anchor = JSON.parse(opts.anchorJson);
|
|
1767
|
+
} catch (unused) {
|
|
1768
|
+
console.error('--anchor-json is not valid JSON.');
|
|
1769
|
+
process.exit(1);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
return [
|
|
1773
|
+
4,
|
|
1774
|
+
resolveAuthOrConfig()
|
|
1775
|
+
];
|
|
1776
|
+
case 1:
|
|
1777
|
+
auth = _state.sent();
|
|
1778
|
+
client = createClient(auth);
|
|
1779
|
+
_state.label = 2;
|
|
1780
|
+
case 2:
|
|
1781
|
+
_state.trys.push([
|
|
1782
|
+
2,
|
|
1783
|
+
4,
|
|
1784
|
+
,
|
|
1785
|
+
5
|
|
1786
|
+
]);
|
|
1787
|
+
return [
|
|
1788
|
+
4,
|
|
1789
|
+
client.addComment(subject.shortId, {
|
|
1790
|
+
body: opts.body,
|
|
1791
|
+
anchor: anchor,
|
|
1792
|
+
parentId: opts.parent
|
|
1793
|
+
})
|
|
1794
|
+
];
|
|
1795
|
+
case 3:
|
|
1796
|
+
result = _state.sent();
|
|
1797
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1798
|
+
return [
|
|
1799
|
+
3,
|
|
1800
|
+
5
|
|
1801
|
+
];
|
|
1802
|
+
case 4:
|
|
1803
|
+
err = _state.sent();
|
|
1804
|
+
handleCommentApiError(err);
|
|
1805
|
+
return [
|
|
1806
|
+
3,
|
|
1807
|
+
5
|
|
1808
|
+
];
|
|
1809
|
+
case 5:
|
|
1810
|
+
return [
|
|
1811
|
+
2
|
|
1812
|
+
];
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
})();
|
|
1816
|
+
});
|
|
1817
|
+
// --- comment list ---
|
|
1818
|
+
program.commands.find(function(c) {
|
|
1819
|
+
return c.name() === 'comment';
|
|
1820
|
+
}).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) {
|
|
1821
|
+
return _async_to_generator(function() {
|
|
1822
|
+
var subject, auth, client, result, err;
|
|
1823
|
+
return _ts_generator(this, function(_state) {
|
|
1824
|
+
switch(_state.label){
|
|
1825
|
+
case 0:
|
|
1826
|
+
subject = resolveSubjectFlags(opts);
|
|
1827
|
+
if (subject.kind === 'invalid') {
|
|
1828
|
+
console.error(subject.error);
|
|
1829
|
+
process.exit(1);
|
|
1830
|
+
}
|
|
1831
|
+
if (subject.kind === 'kb_page') {
|
|
1832
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
1833
|
+
process.exit(1);
|
|
1834
|
+
}
|
|
1835
|
+
if (opts.status && ![
|
|
1836
|
+
'open',
|
|
1837
|
+
'resolved',
|
|
1838
|
+
'all'
|
|
1839
|
+
].includes(opts.status)) {
|
|
1840
|
+
console.error("Invalid --status: ".concat(opts.status, ". Use open, resolved, or all."));
|
|
1841
|
+
process.exit(1);
|
|
1842
|
+
}
|
|
1843
|
+
return [
|
|
1844
|
+
4,
|
|
1845
|
+
resolveAuthOrConfig()
|
|
1846
|
+
];
|
|
1847
|
+
case 1:
|
|
1848
|
+
auth = _state.sent();
|
|
1849
|
+
client = createClient(auth);
|
|
1850
|
+
_state.label = 2;
|
|
1851
|
+
case 2:
|
|
1852
|
+
_state.trys.push([
|
|
1853
|
+
2,
|
|
1854
|
+
4,
|
|
1855
|
+
,
|
|
1856
|
+
5
|
|
1857
|
+
]);
|
|
1858
|
+
return [
|
|
1859
|
+
4,
|
|
1860
|
+
client.listComments(subject.shortId, {
|
|
1861
|
+
status: opts.status,
|
|
1862
|
+
since: opts.since
|
|
1863
|
+
})
|
|
1864
|
+
];
|
|
1865
|
+
case 3:
|
|
1866
|
+
result = _state.sent();
|
|
1867
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1868
|
+
return [
|
|
1869
|
+
3,
|
|
1870
|
+
5
|
|
1871
|
+
];
|
|
1872
|
+
case 4:
|
|
1873
|
+
err = _state.sent();
|
|
1874
|
+
handleCommentApiError(err);
|
|
1875
|
+
return [
|
|
1876
|
+
3,
|
|
1877
|
+
5
|
|
1878
|
+
];
|
|
1879
|
+
case 5:
|
|
1880
|
+
return [
|
|
1881
|
+
2
|
|
1882
|
+
];
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
})();
|
|
1886
|
+
});
|
|
1887
|
+
// --- comment edit ---
|
|
1888
|
+
program.commands.find(function(c) {
|
|
1889
|
+
return c.name() === 'comment';
|
|
1890
|
+
}).command('edit <commentId>').description('Edit your own comment within the 5-minute author window.').requiredOption('--body <text>', 'New comment body').action(function(commentId, opts) {
|
|
1891
|
+
return _async_to_generator(function() {
|
|
1892
|
+
var auth, client, result, err;
|
|
1893
|
+
return _ts_generator(this, function(_state) {
|
|
1894
|
+
switch(_state.label){
|
|
1895
|
+
case 0:
|
|
1896
|
+
return [
|
|
1897
|
+
4,
|
|
1898
|
+
resolveAuthOrConfig()
|
|
1899
|
+
];
|
|
1900
|
+
case 1:
|
|
1901
|
+
auth = _state.sent();
|
|
1902
|
+
client = createClient(auth);
|
|
1903
|
+
_state.label = 2;
|
|
1904
|
+
case 2:
|
|
1905
|
+
_state.trys.push([
|
|
1906
|
+
2,
|
|
1907
|
+
4,
|
|
1908
|
+
,
|
|
1909
|
+
5
|
|
1910
|
+
]);
|
|
1911
|
+
return [
|
|
1912
|
+
4,
|
|
1913
|
+
client.editComment(commentId, opts.body)
|
|
1914
|
+
];
|
|
1915
|
+
case 3:
|
|
1916
|
+
result = _state.sent();
|
|
1917
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1918
|
+
return [
|
|
1919
|
+
3,
|
|
1920
|
+
5
|
|
1921
|
+
];
|
|
1922
|
+
case 4:
|
|
1923
|
+
err = _state.sent();
|
|
1924
|
+
handleCommentApiError(err);
|
|
1925
|
+
return [
|
|
1926
|
+
3,
|
|
1927
|
+
5
|
|
1928
|
+
];
|
|
1929
|
+
case 5:
|
|
1930
|
+
return [
|
|
1931
|
+
2
|
|
1932
|
+
];
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
})();
|
|
1936
|
+
});
|
|
1937
|
+
// --- comment delete ---
|
|
1938
|
+
program.commands.find(function(c) {
|
|
1939
|
+
return c.name() === 'comment';
|
|
1940
|
+
}).command('delete <commentId>').description('Soft-delete a comment. Author / artifact creator / org admin.').action(function(commentId) {
|
|
1941
|
+
return _async_to_generator(function() {
|
|
1942
|
+
var auth, client, err;
|
|
1943
|
+
return _ts_generator(this, function(_state) {
|
|
1944
|
+
switch(_state.label){
|
|
1945
|
+
case 0:
|
|
1946
|
+
return [
|
|
1947
|
+
4,
|
|
1948
|
+
resolveAuthOrConfig()
|
|
1949
|
+
];
|
|
1950
|
+
case 1:
|
|
1951
|
+
auth = _state.sent();
|
|
1952
|
+
client = createClient(auth);
|
|
1953
|
+
_state.label = 2;
|
|
1954
|
+
case 2:
|
|
1955
|
+
_state.trys.push([
|
|
1956
|
+
2,
|
|
1957
|
+
4,
|
|
1958
|
+
,
|
|
1959
|
+
5
|
|
1960
|
+
]);
|
|
1961
|
+
return [
|
|
1962
|
+
4,
|
|
1963
|
+
client.deleteComment(commentId)
|
|
1964
|
+
];
|
|
1965
|
+
case 3:
|
|
1966
|
+
_state.sent();
|
|
1967
|
+
console.log('Comment deleted.');
|
|
1968
|
+
return [
|
|
1969
|
+
3,
|
|
1970
|
+
5
|
|
1971
|
+
];
|
|
1972
|
+
case 4:
|
|
1973
|
+
err = _state.sent();
|
|
1974
|
+
handleCommentApiError(err);
|
|
1975
|
+
return [
|
|
1976
|
+
3,
|
|
1977
|
+
5
|
|
1978
|
+
];
|
|
1979
|
+
case 5:
|
|
1980
|
+
return [
|
|
1981
|
+
2
|
|
1982
|
+
];
|
|
1983
|
+
}
|
|
1984
|
+
});
|
|
1985
|
+
})();
|
|
1986
|
+
});
|
|
1987
|
+
// --- thread resolve / reopen ---
|
|
1988
|
+
var threadCmd = program.command('thread').description('Thread-level operations (resolve, reopen).');
|
|
1989
|
+
threadCmd.command('resolve <rootCommentId>').description('Mark a thread resolved. Thread participant / artifact creator / org admin.').action(function(commentId) {
|
|
1990
|
+
return _async_to_generator(function() {
|
|
1991
|
+
var auth, client, result, err;
|
|
1992
|
+
return _ts_generator(this, function(_state) {
|
|
1993
|
+
switch(_state.label){
|
|
1994
|
+
case 0:
|
|
1995
|
+
return [
|
|
1996
|
+
4,
|
|
1997
|
+
resolveAuthOrConfig()
|
|
1998
|
+
];
|
|
1999
|
+
case 1:
|
|
2000
|
+
auth = _state.sent();
|
|
2001
|
+
client = createClient(auth);
|
|
2002
|
+
_state.label = 2;
|
|
2003
|
+
case 2:
|
|
2004
|
+
_state.trys.push([
|
|
2005
|
+
2,
|
|
2006
|
+
4,
|
|
2007
|
+
,
|
|
2008
|
+
5
|
|
2009
|
+
]);
|
|
2010
|
+
return [
|
|
2011
|
+
4,
|
|
2012
|
+
client.resolveThread(commentId)
|
|
2013
|
+
];
|
|
2014
|
+
case 3:
|
|
2015
|
+
result = _state.sent();
|
|
2016
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2017
|
+
return [
|
|
2018
|
+
3,
|
|
2019
|
+
5
|
|
2020
|
+
];
|
|
2021
|
+
case 4:
|
|
2022
|
+
err = _state.sent();
|
|
2023
|
+
handleCommentApiError(err);
|
|
2024
|
+
return [
|
|
2025
|
+
3,
|
|
2026
|
+
5
|
|
2027
|
+
];
|
|
2028
|
+
case 5:
|
|
2029
|
+
return [
|
|
2030
|
+
2
|
|
2031
|
+
];
|
|
2032
|
+
}
|
|
2033
|
+
});
|
|
2034
|
+
})();
|
|
2035
|
+
});
|
|
2036
|
+
threadCmd.command('reopen <rootCommentId>').description('Reopen a resolved thread. Any authenticated user with view access.').action(function(commentId) {
|
|
2037
|
+
return _async_to_generator(function() {
|
|
2038
|
+
var auth, client, result, err;
|
|
2039
|
+
return _ts_generator(this, function(_state) {
|
|
2040
|
+
switch(_state.label){
|
|
2041
|
+
case 0:
|
|
2042
|
+
return [
|
|
2043
|
+
4,
|
|
2044
|
+
resolveAuthOrConfig()
|
|
2045
|
+
];
|
|
2046
|
+
case 1:
|
|
2047
|
+
auth = _state.sent();
|
|
2048
|
+
client = createClient(auth);
|
|
2049
|
+
_state.label = 2;
|
|
2050
|
+
case 2:
|
|
2051
|
+
_state.trys.push([
|
|
2052
|
+
2,
|
|
2053
|
+
4,
|
|
2054
|
+
,
|
|
2055
|
+
5
|
|
2056
|
+
]);
|
|
2057
|
+
return [
|
|
2058
|
+
4,
|
|
2059
|
+
client.reopenThread(commentId)
|
|
2060
|
+
];
|
|
2061
|
+
case 3:
|
|
2062
|
+
result = _state.sent();
|
|
2063
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2064
|
+
return [
|
|
2065
|
+
3,
|
|
2066
|
+
5
|
|
2067
|
+
];
|
|
2068
|
+
case 4:
|
|
2069
|
+
err = _state.sent();
|
|
2070
|
+
handleCommentApiError(err);
|
|
2071
|
+
return [
|
|
2072
|
+
3,
|
|
2073
|
+
5
|
|
2074
|
+
];
|
|
2075
|
+
case 5:
|
|
2076
|
+
return [
|
|
2077
|
+
2
|
|
2078
|
+
];
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
})();
|
|
2082
|
+
});
|
|
2083
|
+
// --- watch / unwatch ---
|
|
2084
|
+
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) {
|
|
2085
|
+
return _async_to_generator(function() {
|
|
2086
|
+
var subject, auth, client, result, err;
|
|
2087
|
+
return _ts_generator(this, function(_state) {
|
|
2088
|
+
switch(_state.label){
|
|
2089
|
+
case 0:
|
|
2090
|
+
subject = resolveSubjectFlags(opts);
|
|
2091
|
+
if (subject.kind === 'invalid') {
|
|
2092
|
+
console.error(subject.error);
|
|
2093
|
+
process.exit(1);
|
|
2094
|
+
}
|
|
2095
|
+
if (subject.kind === 'kb_page') {
|
|
2096
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
2097
|
+
process.exit(1);
|
|
2098
|
+
}
|
|
2099
|
+
return [
|
|
2100
|
+
4,
|
|
2101
|
+
resolveAuthOrConfig()
|
|
2102
|
+
];
|
|
2103
|
+
case 1:
|
|
2104
|
+
auth = _state.sent();
|
|
2105
|
+
client = createClient(auth);
|
|
2106
|
+
_state.label = 2;
|
|
2107
|
+
case 2:
|
|
2108
|
+
_state.trys.push([
|
|
2109
|
+
2,
|
|
2110
|
+
4,
|
|
2111
|
+
,
|
|
2112
|
+
5
|
|
2113
|
+
]);
|
|
2114
|
+
return [
|
|
2115
|
+
4,
|
|
2116
|
+
client.watchArtifact(subject.shortId)
|
|
2117
|
+
];
|
|
2118
|
+
case 3:
|
|
2119
|
+
result = _state.sent();
|
|
2120
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2121
|
+
return [
|
|
2122
|
+
3,
|
|
2123
|
+
5
|
|
2124
|
+
];
|
|
2125
|
+
case 4:
|
|
2126
|
+
err = _state.sent();
|
|
2127
|
+
handleCommentApiError(err);
|
|
2128
|
+
return [
|
|
2129
|
+
3,
|
|
2130
|
+
5
|
|
2131
|
+
];
|
|
2132
|
+
case 5:
|
|
2133
|
+
return [
|
|
2134
|
+
2
|
|
2135
|
+
];
|
|
2136
|
+
}
|
|
2137
|
+
});
|
|
2138
|
+
})();
|
|
2139
|
+
});
|
|
2140
|
+
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) {
|
|
2141
|
+
return _async_to_generator(function() {
|
|
2142
|
+
var subject, auth, client, err;
|
|
2143
|
+
return _ts_generator(this, function(_state) {
|
|
2144
|
+
switch(_state.label){
|
|
2145
|
+
case 0:
|
|
2146
|
+
subject = resolveSubjectFlags(opts);
|
|
2147
|
+
if (subject.kind === 'invalid') {
|
|
2148
|
+
console.error(subject.error);
|
|
2149
|
+
process.exit(1);
|
|
2150
|
+
}
|
|
2151
|
+
if (subject.kind === 'kb_page') {
|
|
2152
|
+
console.error('subject_type_not_implemented: KB-page subjects are not yet supported.');
|
|
2153
|
+
process.exit(1);
|
|
2154
|
+
}
|
|
2155
|
+
return [
|
|
2156
|
+
4,
|
|
2157
|
+
resolveAuthOrConfig()
|
|
2158
|
+
];
|
|
2159
|
+
case 1:
|
|
2160
|
+
auth = _state.sent();
|
|
2161
|
+
client = createClient(auth);
|
|
2162
|
+
_state.label = 2;
|
|
2163
|
+
case 2:
|
|
2164
|
+
_state.trys.push([
|
|
2165
|
+
2,
|
|
2166
|
+
4,
|
|
2167
|
+
,
|
|
2168
|
+
5
|
|
2169
|
+
]);
|
|
2170
|
+
return [
|
|
2171
|
+
4,
|
|
2172
|
+
client.unwatchArtifact(subject.shortId)
|
|
2173
|
+
];
|
|
2174
|
+
case 3:
|
|
2175
|
+
_state.sent();
|
|
2176
|
+
console.log('Unwatched.');
|
|
2177
|
+
return [
|
|
2178
|
+
3,
|
|
2179
|
+
5
|
|
2180
|
+
];
|
|
2181
|
+
case 4:
|
|
2182
|
+
err = _state.sent();
|
|
2183
|
+
handleCommentApiError(err);
|
|
2184
|
+
return [
|
|
2185
|
+
3,
|
|
2186
|
+
5
|
|
2187
|
+
];
|
|
2188
|
+
case 5:
|
|
2189
|
+
return [
|
|
2190
|
+
2
|
|
2191
|
+
];
|
|
2192
|
+
}
|
|
2193
|
+
});
|
|
2194
|
+
})();
|
|
2195
|
+
});
|
|
2196
|
+
function resolveSubjectFlags(opts) {
|
|
2197
|
+
var hasArtifact = Boolean(opts.artifact);
|
|
2198
|
+
var kbPage = opts.kbPage;
|
|
2199
|
+
var hasKbPage = Array.isArray(kbPage) && kbPage.length > 0;
|
|
2200
|
+
if (hasArtifact && hasKbPage) {
|
|
2201
|
+
return {
|
|
2202
|
+
kind: 'invalid',
|
|
2203
|
+
error: 'Pass either --artifact or --kb-page, not both.'
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
if (!hasArtifact && !hasKbPage) {
|
|
2207
|
+
return {
|
|
2208
|
+
kind: 'invalid',
|
|
2209
|
+
error: 'Pass --artifact <shortId> or --kb-page <kbName> <filePath>.'
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
if (hasArtifact) {
|
|
2213
|
+
return {
|
|
2214
|
+
kind: 'artifact',
|
|
2215
|
+
shortId: opts.artifact
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
if (kbPage.length !== 2) {
|
|
2219
|
+
return {
|
|
2220
|
+
kind: 'invalid',
|
|
2221
|
+
error: '--kb-page requires exactly two values: <kbName> <filePath>.'
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
return {
|
|
2225
|
+
kind: 'kb_page',
|
|
2226
|
+
kbName: kbPage[0],
|
|
2227
|
+
filePath: kbPage[1],
|
|
2228
|
+
shortId: ''
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* Common error mapper for the comment / watch / thread subcommands.
|
|
2233
|
+
* Mirrors the ApiError handling on share/rename so 401 prompts a
|
|
2234
|
+
* re-login, 403 surfaces the API's reason verbatim, 404 shows a
|
|
2235
|
+
* concrete "not found", and 410 (signed-token failures from the
|
|
2236
|
+
* email-link routes) prints the API's message. Other errors fall
|
|
2237
|
+
* through to a generic stringify.
|
|
2238
|
+
*/ function handleCommentApiError(err) {
|
|
2239
|
+
if (_instanceof(err, ApiError)) {
|
|
2240
|
+
if (err.status === 401) {
|
|
2241
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
2242
|
+
process.exit(1);
|
|
2243
|
+
}
|
|
2244
|
+
if (err.status === 404) {
|
|
2245
|
+
console.error(err.message);
|
|
2246
|
+
process.exit(4);
|
|
2247
|
+
}
|
|
2248
|
+
if (err.status === 403 || err.status === 400 || err.status === 410 || err.status === 429) {
|
|
2249
|
+
console.error(err.message);
|
|
2250
|
+
process.exit(1);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
var msg = _instanceof(err, Error) ? err.message : String(err);
|
|
2254
|
+
console.error(msg);
|
|
2255
|
+
process.exit(1);
|
|
2256
|
+
}
|
|
1706
2257
|
// --- mcp ---
|
|
1707
2258
|
program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
|
|
1708
2259
|
return _async_to_generator(function() {
|
|
@@ -1716,6 +2267,7 @@ program.command('mcp').description('Start MCP server over stdin/stdout').action(
|
|
|
1716
2267
|
];
|
|
1717
2268
|
case 1:
|
|
1718
2269
|
auth = _state.sent();
|
|
2270
|
+
setMcpMode();
|
|
1719
2271
|
if (!auth) return [
|
|
1720
2272
|
3,
|
|
1721
2273
|
3
|
|
@@ -1723,7 +2275,8 @@ program.command('mcp').description('Start MCP server over stdin/stdout').action(
|
|
|
1723
2275
|
client = new ApiClient({
|
|
1724
2276
|
baseUrl: auth.apiUrl,
|
|
1725
2277
|
apiKey: auth.apiKey,
|
|
1726
|
-
clientType: 'mcp-stdio'
|
|
2278
|
+
clientType: 'mcp-stdio',
|
|
2279
|
+
version: version
|
|
1727
2280
|
});
|
|
1728
2281
|
return [
|
|
1729
2282
|
4,
|
|
@@ -1743,7 +2296,8 @@ program.command('mcp').description('Start MCP server over stdin/stdout').action(
|
|
|
1743
2296
|
publicClient = new ApiClient({
|
|
1744
2297
|
baseUrl: resolvePublicApiUrl(),
|
|
1745
2298
|
apiKey: '',
|
|
1746
|
-
clientType: 'mcp-stdio'
|
|
2299
|
+
clientType: 'mcp-stdio',
|
|
2300
|
+
version: version
|
|
1747
2301
|
});
|
|
1748
2302
|
return [
|
|
1749
2303
|
4,
|