@yadsh/dsh-web-fetch-authenticated 0.2.0 → 0.3.1
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/README.md +66 -3
- package/compatibility.json +2 -2
- package/lib/adapters/confluence.js +406 -0
- package/lib/adapters/confluence.js.map +1 -0
- package/lib/adapters/index.js +65 -0
- package/lib/adapters/index.js.map +1 -0
- package/lib/adapters/jira.js +511 -0
- package/lib/adapters/jira.js.map +1 -0
- package/lib/adapters/markup.js +221 -0
- package/lib/adapters/markup.js.map +1 -0
- package/lib/client/index.js +5 -4
- package/lib/client/index.js.map +1 -1
- package/lib/client/sections.js +43 -16
- package/lib/client/sections.js.map +1 -1
- package/lib/client.js +149 -29
- package/lib/client.js.map +1 -1
- package/lib/config.js +15 -0
- package/lib/config.js.map +1 -1
- package/lib/errors.js +5 -0
- package/lib/errors.js.map +1 -1
- package/lib/index.js +10 -9
- package/lib/index.js.map +1 -1
- package/lib/provider.js +7 -3
- package/lib/provider.js.map +1 -1
- package/lib/rule-validation.js +22 -0
- package/lib/rule-validation.js.map +1 -1
- package/lib/testing.js +7 -5
- package/lib/testing.js.map +1 -1
- package/lib/typert.host.js +6 -4
- package/lib/typert.remote-client.js +5 -3
- package/lib/types/adapters/confluence.d.ts +46 -0
- package/lib/types/adapters/index.d.ts +30 -0
- package/lib/types/adapters/jira.d.ts +55 -0
- package/lib/types/adapters/markup.d.ts +31 -0
- package/lib/types/client/sections.d.ts +9 -3
- package/lib/types/errors.d.ts +3 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/types.d.ts +31 -0
- package/package.json +30 -27
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jira content adapter (SPEC §15.2): recognize `/browse/<ISSUE-KEY>` style
|
|
3
|
+
* URLs, fetch the issue through the Jira REST API with the SAME authenticated
|
|
4
|
+
* transport (so network policy, credentials, and limits apply unchanged), and
|
|
5
|
+
* normalize the response into compact Markdown text — one dense block of the
|
|
6
|
+
* fields the model actually needs instead of a page of application chrome.
|
|
7
|
+
* Server/Data Center issues carry wiki-markup descriptions; Cloud issues
|
|
8
|
+
* carry Atlassian Document Format bodies; both convert to Markdown here.
|
|
9
|
+
* @module adapters/jira
|
|
10
|
+
*/
|
|
11
|
+
import type { ResolvedAdapter, ResolvedRule } from '../types.js';
|
|
12
|
+
import type { ResolvedAuthSecrets } from '../auth/index.js';
|
|
13
|
+
import type { TransportGlobals } from '../transport/fetch.js';
|
|
14
|
+
/** REST JSON payload the adapter consumes. */
|
|
15
|
+
export type FetchJson = (url: URL) => Promise<{
|
|
16
|
+
statusCode: number;
|
|
17
|
+
data: unknown;
|
|
18
|
+
}>;
|
|
19
|
+
/** Everything an adapter needs beyond the URL; mirrors the transport options. */
|
|
20
|
+
export interface AdapterRequestContext {
|
|
21
|
+
readonly rule: ResolvedRule;
|
|
22
|
+
readonly globals: TransportGlobals;
|
|
23
|
+
readonly resolveSecrets: (rule: ResolvedRule) => Promise<ResolvedAuthSecrets>;
|
|
24
|
+
readonly signal?: AbortSignal;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extract an issue key from a URL path. Recognizes `/browse/KEY` at any depth
|
|
28
|
+
* (deployments under `/jira/browse/…`) and `/issues/KEY`. Returns `undefined`
|
|
29
|
+
* for URLs the adapter cannot map, so the caller falls back to raw HTML.
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractIssueKey(pathname: string): string | undefined;
|
|
32
|
+
/** Build the REST issue URL for the configured flavor. */
|
|
33
|
+
export declare function issueApiUrl(origin: string, key: string, adapter: ResolvedAdapter, includeQuery?: boolean): URL;
|
|
34
|
+
/** REST paging path of the issue's comments, used by the tester's diagnostics. */
|
|
35
|
+
export declare function commentApiPath(key: string, adapter: ResolvedAdapter): string;
|
|
36
|
+
/** Fetch a Jira issue and normalize it into Markdown text (SPEC §15.2). */
|
|
37
|
+
export declare function fetchIssueMarkdown(requestUrl: URL, adapter: ResolvedAdapter, fetchJson: FetchJson): Promise<{
|
|
38
|
+
statusCode: number;
|
|
39
|
+
markdown: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Convert a description body (wiki markup or ADF) into Markdown. */
|
|
42
|
+
export declare function renderDescription(body: unknown): string;
|
|
43
|
+
/**
|
|
44
|
+
* Convert Jira wiki markup to Markdown. Handles the heading, list, table,
|
|
45
|
+
* block, and code constructs that occur in issue descriptions; inline markup
|
|
46
|
+
* converts conservatively and unknown macros pass through as text.
|
|
47
|
+
*/
|
|
48
|
+
export declare function wikiMarkupToMarkdown(source: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Convert an ADF document to Markdown. Recognizes the standard text block
|
|
51
|
+
* structure (paragraphs, headings, lists, code, quotes, tables); unknown node
|
|
52
|
+
* types render their descendant text so content is never silently dropped.
|
|
53
|
+
*/
|
|
54
|
+
export declare function adfToMarkdown(document: unknown): string;
|
|
55
|
+
//# sourceMappingURL=jira.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tiny well-formed XML/XHTML reader for content adapters (SPEC §15.2).
|
|
3
|
+
* Confluence storage bodies are well-formed XHTML, so a strict recursive
|
|
4
|
+
* descent parser without external dependencies is enough; anything malformed
|
|
5
|
+
* surfaces as a thrown `Error` the adapter maps to a structured failure.
|
|
6
|
+
* Pure text in, node tree out — no Node or DOM dependencies.
|
|
7
|
+
* @module adapters/markup
|
|
8
|
+
*/
|
|
9
|
+
/** A parsed markup node: an element, a text run, or a comment. */
|
|
10
|
+
export type MarkupNode = MarkupElement | MarkupText;
|
|
11
|
+
export interface MarkupElement {
|
|
12
|
+
readonly kind: 'element';
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly attrs: Readonly<Record<string, string>>;
|
|
15
|
+
readonly children: MarkupNode[];
|
|
16
|
+
}
|
|
17
|
+
export interface MarkupText {
|
|
18
|
+
readonly kind: 'text';
|
|
19
|
+
readonly value: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function isElement(node: MarkupNode | undefined): node is MarkupElement;
|
|
22
|
+
export declare function isText(node: MarkupNode | undefined): node is MarkupText;
|
|
23
|
+
/** Decode the XML built-in entities plus numeric references; unknown ones pass through. */
|
|
24
|
+
export declare function decodeEntities(text: string): string;
|
|
25
|
+
/** Parse a well-formed XML/XHTML document fragment into a node tree. */
|
|
26
|
+
export declare function parseMarkup(source: string): MarkupNode[];
|
|
27
|
+
/** Concatenated descendant text of a subtree, with block-ish whitespace collapsed. */
|
|
28
|
+
export declare function textContent(nodes: readonly MarkupNode[]): string;
|
|
29
|
+
/** First descendant element with the given (lower-case) name, depth-first. */
|
|
30
|
+
export declare function findElement(nodes: readonly MarkupNode[], name: string): MarkupElement | undefined;
|
|
31
|
+
//# sourceMappingURL=markup.d.ts.map
|
|
@@ -5,17 +5,23 @@
|
|
|
5
5
|
* asks the credentials domain only for configured/writable facts.
|
|
6
6
|
* @module client/sections
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
9
|
-
import type { SettingsScope } from '@deepseek-ai/dsh-client-
|
|
8
|
+
import type { CredentialInfo } from '@deepseek-ai/dsh-credentials/types';
|
|
9
|
+
import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
10
10
|
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
11
11
|
import type { DiagnoseReport, ProviderStatusReport, RuleTestReport, WebFetchAuthConfig, AuthenticatedFetchRule } from '../types.js';
|
|
12
|
+
/** Client face of the Host `credentials` Remote namespace (values never ride it). */
|
|
13
|
+
export interface CredentialsRemote {
|
|
14
|
+
describe(refs: string[]): Promise<RemoteResult<Record<string, CredentialInfo>>>;
|
|
15
|
+
set(ref: string, value: string): Promise<RemoteResult<void>>;
|
|
16
|
+
unset(ref: string): Promise<RemoteResult<void>>;
|
|
17
|
+
}
|
|
12
18
|
/** Client face injected into the card. */
|
|
13
19
|
export interface CardFace {
|
|
14
20
|
scope: SettingsScope<WebFetchAuthConfig>;
|
|
15
21
|
status: () => Promise<RemoteResult<ProviderStatusReport>>;
|
|
16
22
|
testRule: (ruleId: string, url?: string) => Promise<RemoteResult<RuleTestReport>>;
|
|
17
23
|
diagnose: (url: string) => Promise<RemoteResult<DiagnoseReport>>;
|
|
18
|
-
credentials:
|
|
24
|
+
credentials: CredentialsRemote;
|
|
19
25
|
}
|
|
20
26
|
/** Provider overview: status, selection, counts, config errors (SPEC §6.1). */
|
|
21
27
|
export declare function StatusSection({ status: report, warnings }: {
|
package/lib/types/errors.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare const AUTH_FETCH_ERROR_CODES: {
|
|
|
22
22
|
readonly timeout: 'AUTH_FETCH_TIMEOUT';
|
|
23
23
|
readonly invalidUrl: 'AUTH_FETCH_INVALID_URL';
|
|
24
24
|
readonly providerError: 'AUTH_FETCH_PROVIDER_ERROR';
|
|
25
|
+
readonly adapterFailed: 'AUTH_FETCH_ADAPTER_FAILED';
|
|
25
26
|
};
|
|
26
27
|
/** Scrub free text before it enters an error message. */
|
|
27
28
|
export declare function sanitizedDetail(error: unknown, maxLength?: number): string;
|
|
@@ -40,4 +41,6 @@ export declare function unsupportedCharset(charset: string): WebError;
|
|
|
40
41
|
export declare function timeout(): WebError;
|
|
41
42
|
export declare function aborted(cause?: unknown): WebError;
|
|
42
43
|
export declare function providerError(detail: string, cause?: unknown): WebError;
|
|
44
|
+
/** A content adapter could not produce its normalized text (SPEC §15.2). */
|
|
45
|
+
export declare function adapterFailed(detail: string, cause?: unknown): WebError;
|
|
43
46
|
//# sourceMappingURL=errors.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ declare module '@deepseek-ai/cordis' {
|
|
|
26
26
|
/** Cordis plugin ID. */
|
|
27
27
|
export declare const name = "web-fetch-authenticated";
|
|
28
28
|
export declare const inject: string[];
|
|
29
|
-
export declare const WEB_FETCH_AUTH_SETTINGS_NAMESPACE
|
|
29
|
+
export declare const WEB_FETCH_AUTH_SETTINGS_NAMESPACE = "web-fetch-authenticated";
|
|
30
30
|
export type Config = WebFetchAuthConfig;
|
|
31
31
|
export declare const Config: import("@deepseek-ai/schemastery").default<WebFetchAuthConfig>;
|
|
32
32
|
/** The host-side Remote face the browser card calls. */
|
package/lib/types/types.d.ts
CHANGED
|
@@ -70,6 +70,32 @@ export type AuthConfig = {
|
|
|
70
70
|
readonly credential: string;
|
|
71
71
|
readonly prefix?: string;
|
|
72
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* Per-rule content adapter (SPEC §15.2): `none` returns the raw response to
|
|
75
|
+
* `dsh-tool-web` (HTML → Markdown conversion upstream); `jira` and
|
|
76
|
+
* `confluence` rewrite a recognized URL to the product's REST API, fetch it
|
|
77
|
+
* through the same authenticated transport, and normalize the response into
|
|
78
|
+
* compact Markdown text.
|
|
79
|
+
*/
|
|
80
|
+
export type AdapterType = 'none' | 'jira' | 'confluence';
|
|
81
|
+
/** Which Jira REST dialect to speak (SPEC §15.2: Server/DC/Cloud differ). */
|
|
82
|
+
export type JiraFlavor = 'server' | 'cloud';
|
|
83
|
+
export interface AdapterConfig {
|
|
84
|
+
readonly type: AdapterType;
|
|
85
|
+
/** Jira only: REST API flavor. Default `server` (REST v2, wiki-markup bodies). */
|
|
86
|
+
readonly jiraFlavor?: JiraFlavor;
|
|
87
|
+
/** Jira only: include issue comments in the normalized text. Default `false`. */
|
|
88
|
+
readonly includeComments?: boolean;
|
|
89
|
+
/** Jira only: include issue links (blocks/duplicates/…) in the text. Default `false`. */
|
|
90
|
+
readonly includeLinks?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/** Fully resolved adapter settings of a rule (defaults applied). */
|
|
93
|
+
export interface ResolvedAdapter {
|
|
94
|
+
readonly type: AdapterType;
|
|
95
|
+
readonly jiraFlavor: JiraFlavor;
|
|
96
|
+
readonly includeComments: boolean;
|
|
97
|
+
readonly includeLinks: boolean;
|
|
98
|
+
}
|
|
73
99
|
/** Match section of a rule (SPEC §7/§9): exact hosts, glob paths. */
|
|
74
100
|
export interface RuleMatch {
|
|
75
101
|
/** Default `['https']`. */
|
|
@@ -97,6 +123,8 @@ export interface AuthenticatedFetchRule {
|
|
|
97
123
|
networkPolicy?: NetworkPolicy;
|
|
98
124
|
redirects?: RedirectPolicy;
|
|
99
125
|
limits?: FetchLimits;
|
|
126
|
+
/** Optional content adapter (SPEC §15.2). Omitted = raw HTTP/HTML passthrough. */
|
|
127
|
+
adapter?: AdapterConfig;
|
|
100
128
|
}
|
|
101
129
|
/** What happens when no rule matches (SPEC §17). v1 supports `block` only. */
|
|
102
130
|
export type UnmatchedPolicy = 'block';
|
|
@@ -143,6 +171,7 @@ export interface ResolvedRule {
|
|
|
143
171
|
readonly networkPolicy: ResolvedNetworkPolicy;
|
|
144
172
|
readonly redirects: ResolvedRedirectPolicy;
|
|
145
173
|
readonly limits: ResolvedLimits;
|
|
174
|
+
readonly adapter: ResolvedAdapter;
|
|
146
175
|
}
|
|
147
176
|
export interface ResolvedConfig {
|
|
148
177
|
readonly configVersion: number;
|
|
@@ -199,6 +228,8 @@ export interface RuleTestReport {
|
|
|
199
228
|
readonly detail?: string;
|
|
200
229
|
/** Short secret-scrubbed response preview. */
|
|
201
230
|
readonly preview?: string;
|
|
231
|
+
/** Adapter applied for the request (`jira`/`confluence`) when the rule selects one. */
|
|
232
|
+
readonly adapter?: string;
|
|
202
233
|
readonly truncated: boolean;
|
|
203
234
|
}
|
|
204
235
|
/** Sanitized match/policy diagnosis without performing the HTTP request (SPEC §6.4). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yadsh/dsh-web-fetch-authenticated",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Authenticated, policy-gated WebFetchProvider for the DeepSeek Harness web capability seam (ctx.web)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -48,7 +48,6 @@
|
|
|
48
48
|
"inject": [
|
|
49
49
|
"@deepseek-ai/dsh-api-gateway",
|
|
50
50
|
"@deepseek-ai/dsh-client-connection",
|
|
51
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
52
51
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
53
52
|
"@deepseek-ai/dsh-client-ui-settings-plugins"
|
|
54
53
|
],
|
|
@@ -66,45 +65,49 @@
|
|
|
66
65
|
"LICENSE"
|
|
67
66
|
],
|
|
68
67
|
"keywords": [
|
|
68
|
+
"deepseek",
|
|
69
69
|
"deepseek-harness",
|
|
70
70
|
"dsh",
|
|
71
|
+
"dsh-plugin",
|
|
72
|
+
"cordis",
|
|
71
73
|
"web-fetch",
|
|
72
74
|
"ssrf",
|
|
73
75
|
"credentials",
|
|
74
|
-
"
|
|
76
|
+
"security",
|
|
77
|
+
"fetch"
|
|
75
78
|
],
|
|
76
79
|
"license": "MIT",
|
|
77
80
|
"peerDependencies": {
|
|
78
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
79
|
-
"@deepseek-ai/dsh-client-connection": ">=0.1.
|
|
80
|
-
"@deepseek-ai/dsh-client-
|
|
81
|
-
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.
|
|
82
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.
|
|
83
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.
|
|
84
|
-
"@deepseek-ai/dsh-credentials": ">=0.1.
|
|
85
|
-
"@deepseek-ai/dsh-settings": ">=0.1.
|
|
86
|
-
"@deepseek-ai/dsh-typert-protocol": ">=0.1.
|
|
87
|
-
"@deepseek-ai/dsh-web": ">=0.1.
|
|
88
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
81
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
82
|
+
"@deepseek-ai/dsh-client-connection": ">=0.1.5-rc.2 <0.2.0",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.2 <0.2.0",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.2 <0.2.0",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.5-rc.2 <0.2.0",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.2 <0.2.0",
|
|
87
|
+
"@deepseek-ai/dsh-credentials": ">=0.1.5-rc.2 <0.2.0",
|
|
88
|
+
"@deepseek-ai/dsh-settings": ">=0.1.5-rc.2 <0.2.0",
|
|
89
|
+
"@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.2 <0.2.0",
|
|
90
|
+
"@deepseek-ai/dsh-web": ">=0.1.5-rc.2 <0.2.0",
|
|
91
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
89
92
|
"react": "^18.2.0"
|
|
90
93
|
},
|
|
91
94
|
"dependencies": {
|
|
92
95
|
"zod": "^4.4.3",
|
|
93
|
-
"@yadsh/dsh-plugin-log": "^0.
|
|
96
|
+
"@yadsh/dsh-plugin-log": "^0.3.0"
|
|
94
97
|
},
|
|
95
98
|
"devDependencies": {
|
|
96
|
-
"@deepseek-ai/cordis": "4.0.
|
|
97
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
98
|
-
"@deepseek-ai/dsh-client-
|
|
99
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.
|
|
100
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.
|
|
101
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
102
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
103
|
-
"@deepseek-ai/dsh-settings": "0.1.
|
|
104
|
-
"@deepseek-ai/dsh-typert-generator": "0.1.
|
|
105
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.
|
|
106
|
-
"@deepseek-ai/dsh-web": "0.1.
|
|
107
|
-
"@deepseek-ai/schemastery": "3.18.
|
|
99
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
100
|
+
"@deepseek-ai/dsh-client-connection": "0.1.5-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2",
|
|
104
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
|
|
105
|
+
"@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
|
|
106
|
+
"@deepseek-ai/dsh-settings": "0.1.5-rc.2",
|
|
107
|
+
"@deepseek-ai/dsh-typert-generator": "0.1.5-rc.2",
|
|
108
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-web": "0.1.5-rc.2",
|
|
110
|
+
"@deepseek-ai/schemastery": "3.18.2",
|
|
108
111
|
"@types/node": "^26.4.0",
|
|
109
112
|
"@types/react": "18.3.28",
|
|
110
113
|
"eslint": "10.9.1",
|