@awiki/dsh-pap 0.1.0 → 0.1.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.
@@ -9,20 +9,49 @@ function httpsLink(value) { try {
9
9
  catch {
10
10
  return undefined;
11
11
  } }
12
+ const styles = `
13
+ .dsh-pap-settings{display:grid;gap:16px;max-width:960px;font:14px/1.6 system-ui,sans-serif;color:var(--dsw-alias-label-primary,inherit)}
14
+ .dsh-pap-settings h2,.dsh-pap-settings h3,.dsh-pap-settings p{margin:0}
15
+ .dsh-pap-settings h2{font-size:22px}.dsh-pap-settings h3{font-size:17px}
16
+ .dsh-pap-settings form,.dsh-pap-settings .pap-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
17
+ .dsh-pap-settings input,.dsh-pap-settings select,.dsh-pap-settings button{font:inherit;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#8885);border-radius:8px;padding:7px 10px;color:inherit;background:var(--dsw-alias-bg-layer-2,transparent)}
18
+ .dsh-pap-settings input,.dsh-pap-settings select{max-width:100%}.dsh-pap-settings button:not(:disabled){cursor:pointer}
19
+ .dsh-pap-settings button:disabled{opacity:.5}.dsh-pap-settings select{min-width:180px}
20
+ .dsh-pap-settings article{border:1px solid var(--dsw-alias-border-l2,#8885);border-radius:12px;padding:16px;display:grid;gap:12px}
21
+ .dsh-pap-settings .pap-operation{border-top:1px solid var(--dsw-alias-border-l2,#8885);padding-top:12px;display:grid;gap:8px}
22
+ .dsh-pap-settings .pap-route{font:13px/1.7 ui-monospace,SFMono-Regular,monospace;overflow-wrap:anywhere}
23
+ .dsh-pap-settings .pap-muted{font-size:12px;color:var(--dsw-alias-label-tertiary,#888)}
24
+ .dsh-pap-settings summary{cursor:pointer;font-size:13px;user-select:none}.dsh-pap-settings details[open]>summary{margin-bottom:10px}
25
+ .dsh-pap-settings .pap-session{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:6px 0}
26
+ .dsh-pap-settings .pap-badge{font-size:12px;padding:2px 7px;border-radius:6px;background:var(--dsw-alias-bg-layer-2,#8881)}
27
+ .dsh-pap-settings [role=alert]{color:var(--dsw-alias-status-error,#c33)}
28
+ `;
12
29
  export function PapSettings({ controller }) {
13
30
  const view = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
14
- const [identity, setIdentity] = useState('');
31
+ const [choice, setIdentity] = useState(null);
15
32
  const [domain, setDomain] = useState('');
16
33
  const busy = view.pending || view.loading;
34
+ const identity = choice ?? (view.status.identity ? identityKey(view.status.identity) : '');
17
35
  const run = (input) => { void controller.execute(input); };
18
- return _jsxs("section", { "aria-label": "PAP \u8BBE\u7F6E", style: { display: 'grid', gap: 12, maxWidth: 960 }, children: [_jsx("h2", { children: "PAP Company \u8FDE\u63A5" }), _jsxs("p", { role: "status", children: ["\u72B6\u6001\uFF1A", stateNames[view.status.state] ?? '暂不可用'] }), _jsx("p", { children: "\u5148\u9009\u62E9\u5DF2\u53D1\u5E03\u8EAB\u4EFD\uFF0C\u518D\u53D1\u73B0 Company \u5E76\u5EFA\u7ACB\u8FDE\u63A5\u3002\u53EA\u6709\u4F60\u660E\u786E\u5141\u8BB8\u7684\u64CD\u4F5C\u4F1A\u63D0\u4F9B\u7ED9 Agent\u3002" }), _jsx("button", { disabled: busy, onClick: () => { void controller.refresh(); }, children: "\u5237\u65B0\u72B6\u6001" }), view.error && _jsx("p", { role: "alert", children: view.error }), view.status.authenticationHints.map(hint => _jsxs("p", { role: "status", children: ["\u8BE5\u64CD\u4F5C\u9700\u8981\u68C0\u67E5\u8D26\u6237\u6743\u9650\uFF1A", hint.scope?.join('、') ?? '请检查当前账户授权', " ", httpsLink(hint.resourceMetadataUrl) && _jsx("a", { href: httpsLink(hint.resourceMetadataUrl), target: "_blank", rel: "noopener noreferrer", children: "\u67E5\u770B\u8D44\u6E90\u6388\u6743\u8BF4\u660E" })] }, hint.operationRef)), view.status.state === 'disabled' && _jsx("p", { children: "\u8BF7\u5148\u5728 Host \u914D\u7F6E\u4E2D\u542F\u7528 PAP\uFF0C\u5E76\u914D\u7F6E\u5DF2\u6279\u51C6\u7684\u8EAB\u4EFD\u653F\u7B56\u3002" }), view.status.state === 'migration_required' && _jsxs("div", { children: [_jsx("p", { children: "\u65E7\u8D26\u6237\u51ED\u636E\u5386\u53F2\u4E0D\u5B8C\u6574\uFF0CAgent \u64CD\u4F5C\u5DF2\u505C\u6B62\u3002\u9000\u51FA\u5F53\u524D\u8D26\u6237\u4E0D\u4F1A\u8BC1\u660E\u5168\u90E8\u65E7\u51ED\u636E\u5DF2\u5931\u6548\uFF1B\u8BF7\u4FDD\u7559\u52A0\u5BC6\u72B6\u6001\uFF0C\u7531\u53D7\u4FE1\u7BA1\u7406\u6838\u9A8C\u5168\u90E8\u65E7\u51ED\u636E\u64A4\u9500\u540E\u5904\u7406\u3002" }), view.status.accounts.map(account => _jsxs("p", { children: ["\u8D26\u6237 ", account.accountSlot.slice(-8), " \u00B7 ", account.status, " ", _jsx("button", { disabled: busy || account.status === 'signed_out', onClick: () => run({ action: 'account/sign-out', accountSlot: account.accountSlot }), children: "\u64A4\u9500\u5F53\u524D\u8D26\u6237" })] }, account.accountSlot))] }), view.waitingIdentity && _jsx("p", { role: "status", children: "\u7B49\u5F85\u8EAB\u4EFD\u7BA1\u7406\u670D\u52A1\u3002\u8BF7\u5148\u5728\u201C\u8EAB\u4EFD\u201D\u8BBE\u7F6E\u4E2D\u5B8C\u6210\u6CE8\u518C\u548C\u53D1\u5E03\uFF0C\u518D\u5237\u65B0\u3002" }), !view.waitingIdentity && view.identities.length === 0 && _jsx("p", { children: "\u6682\u65E0\u652F\u6301 PAP Session \u7684\u5DF2\u53D1\u5E03\u8EAB\u4EFD\uFF0C\u8BF7\u5148\u5728\u201C\u8EAB\u4EFD\u201D\u8BBE\u7F6E\u4E2D\u5B8C\u6210\u53D1\u5E03\u3002" }), _jsxs("form", { onSubmit: event => { event.preventDefault(); const selected = view.identities.find(item => identityKey(item.reference) === identity); if (selected)
19
- run({ action: 'identity/select', reference: selected.reference }); }, children: [_jsxs("label", { children: ["\u5DF2\u53D1\u5E03\u8EAB\u4EFD ", _jsxs("select", { "aria-label": "PAP \u8EAB\u4EFD", value: identity, disabled: busy || view.status.state === 'disabled', onChange: event => setIdentity(event.target.value), children: [_jsx("option", { value: "", children: "\u8BF7\u9009\u62E9\u8EAB\u4EFD" }), view.identities.map(item => _jsx("option", { value: identityKey(item.reference), children: item.label }, identityKey(item.reference)))] })] }), _jsx("button", { disabled: busy || !identity || view.status.state === 'disabled', children: "\u4F7F\u7528\u6B64\u8EAB\u4EFD" })] }), _jsxs("form", { onSubmit: event => { event.preventDefault(); run({ action: 'company/discover', domain: domain.trim() }); }, children: [_jsxs("label", { children: ["Company \u57DF\u540D ", _jsx("input", { "aria-label": "Company \u57DF\u540D", value: domain, placeholder: "company.example", onChange: event => setDomain(event.target.value), disabled: busy || view.status.state !== 'ready' })] }), _jsx("button", { disabled: busy || !domain.trim() || view.status.state !== 'ready', children: "\u53D1\u73B0 Company" })] }), view.status.companies.map(company => _jsxs("article", { style: { border: '1px solid #8885', padding: 12 }, children: [_jsx("h3", { children: company.name }), _jsx("p", { children: company.authMode === 'no_as' ? '无需账户即可使用 Session' : company.authMode === 'disabled' ? '暂停新账户登录,已有账户按授权继续使用' : '支持独立账户登录' }), _jsx("button", { disabled: busy, onClick: () => run({ action: 'session/connect', companyRef: company.companyRef }), children: "\u5EFA\u7ACB\u672A\u767B\u5F55\u8FDE\u63A5" }), view.status.sessions.filter(session => session.companyRef === company.companyRef && session.connected).map(session => _jsxs("p", { children: [session.account ? '账户连接' : '未登录连接', " ", session.sessionRef.slice(-8), " ", _jsxs("button", { disabled: busy, onClick: () => run({ action: 'session/disconnect', sessionRef: session.sessionRef }), children: ["\u65AD\u5F00\u8FDE\u63A5 ", session.sessionRef.slice(-8)] })] }, session.sessionRef)), view.status.accounts.filter(account => account.companyRef === company.companyRef).map(account => _jsxs("div", { children: [_jsxs("span", { children: ["\u8D26\u6237 ", account.accountSlot.slice(-8), " \u00B7 ", account.status, " \u00B7 ", account.scopes.join('、')] }), account.status === 'active' && _jsx("button", { disabled: busy, onClick: () => run({ action: 'session/connect', companyRef: company.companyRef, accountSlot: account.accountSlot }), children: "\u5EFA\u7ACB\u8D26\u6237\u8FDE\u63A5" }), account.status === 'active' && _jsx("button", { disabled: busy || !account.canRefresh, onClick: () => run({ action: 'account/refresh', accountSlot: account.accountSlot }), children: "\u5237\u65B0\u8D26\u6237" }), !['signed_out'].includes(account.status) && _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/sign-out', accountSlot: account.accountSlot }), children: "\u9000\u51FA\u8D26\u6237" })] }, account.accountSlot)), view.operations.filter(operation => operation.companyRef === company.companyRef).map(operation => _jsx(Operation, { operation: operation, company: company, view: view, controller: controller }, operation.operationRef))] }, company.companyRef)), view.status.pendingSignIns.map(pending => _jsxs("div", { children: [_jsx("p", { children: "\u8D26\u6237\u767B\u5F55\u7B49\u5F85\u5B8C\u6210\u3002" }), view.authorization?.transactionRef === pending.transactionRef && _jsx("a", { href: view.authorization.url, target: "_blank", rel: "noopener noreferrer", children: "\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u8D26\u6237\u767B\u5F55" }), _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/collect', transactionRef: pending.transactionRef }), children: "\u9886\u53D6\u767B\u5F55\u7ED3\u679C" }), _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/sign-out', accountSlot: pending.accountSlot }), children: "\u53D6\u6D88\u8D26\u6237\u767B\u5F55" })] }, pending.transactionRef))] });
36
+ return _jsxs("section", { "aria-label": "PAP \u8BBE\u7F6E", className: "dsh-pap-settings", children: [_jsx("style", { children: styles }), _jsxs("div", { className: "pap-actions", children: [_jsx("h2", { children: "PAP Company \u8FDE\u63A5" }), _jsx("span", { className: "pap-badge", role: "status", children: stateNames[view.status.state] ?? '暂不可用' }), _jsx("button", { disabled: busy, onClick: () => { void controller.refresh(); }, children: "\u5237\u65B0\u72B6\u6001" })] }), _jsx("p", { children: "\u9009\u62E9\u8EAB\u4EFD \u2192 \u586B\u5199 Company \u2192 \u5EFA\u7ACB\u8FDE\u63A5 \u2192 \u5141\u8BB8\u6240\u9700\u64CD\u4F5C\u3002\u53EA\u6709\u660E\u786E\u5141\u8BB8\u7684\u64CD\u4F5C\u4F1A\u63D0\u4F9B\u7ED9 Agent\u3002" }), _jsx("p", { className: "pap-muted", children: "\u514D\u767B\u5F55\u670D\u52A1\u65E0\u9700\u8D26\u6237\u3001scope \u6216\u9A8C\u8BC1\u7801\u3002\u8FDE\u63A5\u7F16\u53F7\u3001\u8D26\u6237\u6743\u9650\u548C\u6392\u67E5\u4FE1\u606F\u5728\u4E0B\u65B9\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u3002" }), view.error && _jsx("p", { role: "alert", children: view.error }), view.status.authenticationHints.map(hint => _jsxs("p", { role: "status", children: ["\u8BE5\u64CD\u4F5C\u9700\u8981\u68C0\u67E5\u8D26\u6237\u6743\u9650\uFF1A", hint.scope?.join('、') ?? '请检查当前账户授权', " ", httpsLink(hint.resourceMetadataUrl) && _jsx("a", { href: httpsLink(hint.resourceMetadataUrl), target: "_blank", rel: "noopener noreferrer", children: "\u67E5\u770B\u8D44\u6E90\u6388\u6743\u8BF4\u660E" })] }, hint.operationRef)), view.status.state === 'disabled' && _jsx("p", { children: "\u8BF7\u5148\u5728 Host \u914D\u7F6E\u4E2D\u542F\u7528 PAP\uFF0C\u5E76\u914D\u7F6E\u5DF2\u6279\u51C6\u7684\u8EAB\u4EFD\u653F\u7B56\u3002" }), view.status.state === 'migration_required' && _jsxs("div", { children: [_jsx("p", { children: "\u65E7\u8D26\u6237\u51ED\u636E\u5386\u53F2\u4E0D\u5B8C\u6574\uFF0CAgent \u64CD\u4F5C\u5DF2\u505C\u6B62\u3002\u9000\u51FA\u5F53\u524D\u8D26\u6237\u4E0D\u4F1A\u8BC1\u660E\u5168\u90E8\u65E7\u51ED\u636E\u5DF2\u5931\u6548\uFF1B\u8BF7\u4FDD\u7559\u52A0\u5BC6\u72B6\u6001\uFF0C\u7531\u53D7\u4FE1\u7BA1\u7406\u6838\u9A8C\u5168\u90E8\u65E7\u51ED\u636E\u64A4\u9500\u540E\u5904\u7406\u3002" }), view.status.accounts.map(account => _jsxs("p", { children: ["\u8D26\u6237 ", account.accountSlot.slice(-8), " \u00B7 ", account.status, " ", _jsx("button", { disabled: busy || account.status === 'signed_out', onClick: () => run({ action: 'account/sign-out', accountSlot: account.accountSlot }), children: "\u64A4\u9500\u5F53\u524D\u8D26\u6237" })] }, account.accountSlot))] }), view.waitingIdentity && _jsx("p", { role: "status", children: "\u7B49\u5F85\u8EAB\u4EFD\u7BA1\u7406\u670D\u52A1\u3002\u8BF7\u5148\u5728\u201C\u8EAB\u4EFD\u201D\u8BBE\u7F6E\u4E2D\u5B8C\u6210\u6CE8\u518C\u548C\u53D1\u5E03\uFF0C\u518D\u5237\u65B0\u3002" }), !view.waitingIdentity && view.identities.length === 0 && _jsx("p", { children: "\u6682\u65E0\u652F\u6301 PAP Session \u7684\u5DF2\u53D1\u5E03\u8EAB\u4EFD\uFF0C\u8BF7\u5148\u5728\u201C\u8EAB\u4EFD\u201D\u8BBE\u7F6E\u4E2D\u5B8C\u6210\u53D1\u5E03\u3002" }), _jsxs("form", { onSubmit: event => { event.preventDefault(); const selected = view.identities.find(item => identityKey(item.reference) === identity); if (selected)
37
+ run({ action: 'identity/select', reference: selected.reference }); }, children: [_jsxs("label", { children: ["\u5DF2\u53D1\u5E03\u8EAB\u4EFD ", _jsxs("select", { "aria-label": "PAP \u8EAB\u4EFD", value: identity, disabled: busy || view.status.state === 'disabled', onChange: event => setIdentity(event.target.value), children: [_jsx("option", { value: "", children: "\u8BF7\u9009\u62E9\u8EAB\u4EFD" }), view.identities.map(item => _jsx("option", { value: identityKey(item.reference), children: item.label }, identityKey(item.reference)))] })] }), _jsx("button", { disabled: busy || !identity || view.status.state === 'disabled', children: "\u4F7F\u7528\u6B64\u8EAB\u4EFD" })] }), _jsxs("form", { onSubmit: event => { event.preventDefault(); run({ action: 'company/discover', domain: domain.trim() }); }, children: [_jsxs("label", { children: ["Company \u57DF\u540D ", _jsx("input", { "aria-label": "Company \u57DF\u540D", value: domain, placeholder: "company.example", onChange: event => setDomain(event.target.value), disabled: busy || view.status.state !== 'ready' })] }), _jsx("button", { disabled: busy || !domain.trim() || view.status.state !== 'ready', children: "\u53D1\u73B0 Company" })] }), view.status.companies.map(company => _jsx(Company, { company: company, view: view, controller: controller }, company.companyRef)), view.status.pendingSignIns.map(pending => _jsxs("div", { children: [_jsx("p", { children: "\u8D26\u6237\u767B\u5F55\u7B49\u5F85\u5B8C\u6210\u3002" }), view.authorization?.transactionRef === pending.transactionRef && _jsx("a", { href: view.authorization.url, target: "_blank", rel: "noopener noreferrer", children: "\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u8D26\u6237\u767B\u5F55" }), _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/collect', transactionRef: pending.transactionRef }), children: "\u9886\u53D6\u767B\u5F55\u7ED3\u679C" }), _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/sign-out', accountSlot: pending.accountSlot }), children: "\u53D6\u6D88\u8D26\u6237\u767B\u5F55" })] }, pending.transactionRef))] });
38
+ }
39
+ function Company({ company, view, controller }) {
40
+ const sessions = view.status.sessions.filter(session => session.companyRef === company.companyRef && session.connected);
41
+ const accounts = view.status.accounts.filter(account => account.companyRef === company.companyRef);
42
+ const operations = view.operations.filter(operation => operation.companyRef === company.companyRef);
43
+ const connected = sessions.some(session => !session.account);
44
+ const busy = view.pending || view.loading;
45
+ const run = (input) => { void controller.execute(input); };
46
+ return _jsxs("article", { children: [_jsxs("div", { className: "pap-actions", children: [_jsx("h3", { children: company.name }), _jsx("span", { className: "pap-badge", children: company.authMode === 'no_as' ? '免登录' : company.authMode === 'disabled' ? '暂停新账户登录' : '账户登录可选' })] }), _jsxs("div", { className: "pap-actions", children: [_jsxs("span", { children: [sessions.length ? '已连接' : '尚未连接', " \u00B7 \u5DF2\u5141\u8BB8 ", operations.filter(item => item.enabled).length, " \u4E2A\u64CD\u4F5C"] }), _jsx("button", { disabled: busy || connected, onClick: () => run({ action: 'session/connect', companyRef: company.companyRef }), children: connected ? '连接已建立' : '建立未登录连接' })] }), operations.map(operation => _jsx(Operation, { operation: operation, company: company, view: view, controller: controller }, operation.operationRef)), (company.authMode !== 'no_as' || accounts.length > 0) && _jsxs("details", { children: [_jsx("summary", { children: "\u8D26\u6237\u4E0E\u767B\u5F55\uFF08\u53EF\u9009\uFF09" }), _jsx("p", { className: "pap-muted", children: "\u53EA\u6709\u64CD\u4F5C\u660E\u786E\u8981\u6C42\u8D26\u6237\u6743\u9650\u65F6\u624D\u9700\u8981\u767B\u5F55\u3002\u5148\u5728\u8BE5\u64CD\u4F5C\u7684\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u9009\u62E9\u6743\u9650\uFF0C\u518D\u53D1\u8D77\u767B\u5F55\u3002" }), accounts.map(account => _jsxs("div", { className: "pap-session", children: [_jsxs("span", { children: ["\u8D26\u6237 ", account.accountSlot.slice(-8), " \u00B7 ", account.status, " \u00B7 ", account.scopes.join('、')] }), account.status === 'active' && _jsx("button", { disabled: busy, onClick: () => run({ action: 'session/connect', companyRef: company.companyRef, accountSlot: account.accountSlot }), children: "\u5EFA\u7ACB\u8D26\u6237\u8FDE\u63A5" }), account.status === 'active' && _jsx("button", { disabled: busy || !account.canRefresh, onClick: () => run({ action: 'account/refresh', accountSlot: account.accountSlot }), children: "\u5237\u65B0\u8D26\u6237" }), account.status !== 'signed_out' && _jsx("button", { disabled: busy, onClick: () => run({ action: 'account/sign-out', accountSlot: account.accountSlot }), children: "\u9000\u51FA\u8D26\u6237" })] }, account.accountSlot))] }), _jsxs("details", { children: [_jsxs("summary", { children: ["\u8FDE\u63A5\u7BA1\u7406\u4E0E\u8BCA\u65AD\uFF08", sessions.length, " \u4E2A\u8FDE\u63A5\uFF09"] }), _jsx("p", { className: "pap-muted", children: "\u666E\u901A\u4F7F\u7528\u53EA\u9700\u4E00\u4E2A\u672A\u767B\u5F55\u8FDE\u63A5\u3002\u5DF2\u6709\u8FDE\u63A5\u4E0D\u4F1A\u81EA\u52A8\u5408\u5E76\u6216\u5220\u9664\uFF1B\u786E\u8BA4\u4E0D\u518D\u4F7F\u7528\u540E\u53EF\u624B\u52A8\u65AD\u5F00\u3002" }), sessions.map(session => _jsxs("p", { className: "pap-session", children: [session.account ? '账户连接' : '未登录连接', " ", session.sessionRef.slice(-8), " ", _jsxs("button", { disabled: busy, onClick: () => run({ action: 'session/disconnect', sessionRef: session.sessionRef }), children: ["\u65AD\u5F00\u8FDE\u63A5 ", session.sessionRef.slice(-8)] })] }, session.sessionRef))] })] });
20
47
  }
21
48
  function Operation({ operation, company, view, controller }) {
22
- const [sessionRef, setSession] = useState('');
49
+ const [choice, setSession] = useState(null);
23
50
  const [scopes, setScopes] = useState([]);
24
51
  const sessions = view.status.sessions.filter(session => session.companyRef === company.companyRef && session.connected);
52
+ const sessionRef = choice ?? sessions.find(session => !session.account)?.sessionRef ?? '';
25
53
  const selected = sessions.find(session => session.sessionRef === sessionRef);
26
54
  const busy = view.pending || view.loading;
27
- return _jsxs("fieldset", { children: [_jsxs("legend", { children: [operation.method, " ", operation.path] }), _jsx("p", { children: operation.enabled ? '已允许 Agent 调用' : '未允许 Agent 调用' }), _jsxs("label", { children: ["\u64CD\u4F5C\u8FDE\u63A5 ", _jsxs("select", { "aria-label": `连接 ${operation.method} ${operation.path}`, value: sessionRef, onChange: event => setSession(event.target.value), disabled: busy, children: [_jsx("option", { value: "", children: "\u9009\u62E9\u8FDE\u63A5" }), sessions.map(session => _jsxs("option", { value: session.sessionRef, children: [session.account ? '账户' : '未登录', " ", session.sessionRef.slice(-8)] }, session.sessionRef))] })] }), !!company.scopes.length && _jsxs("div", { children: ["\u8D26\u6237\u6743\u9650 ", company.scopes.map(scope => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: scopes.includes(scope), disabled: busy, onChange: event => setScopes(event.target.checked ? [...scopes, scope] : scopes.filter(item => item !== scope)) }), scope] }, scope))] }), _jsx("button", { disabled: busy || !selected, onClick: () => { void controller.execute({ action: 'operation/enable', operationRef: operation.operationRef, sessionRef, scopes: selected?.account ? scopes : [] }); }, children: "\u5141\u8BB8 Agent \u8C03\u7528" }), operation.enabled && _jsx("button", { disabled: busy, onClick: () => { void controller.execute({ action: 'operation/disable', operationRef: operation.operationRef }); }, children: "\u64A4\u9500\u64CD\u4F5C\u8BB8\u53EF" }), _jsx("button", { disabled: busy || !selected || scopes.length === 0 || company.authMode !== 'account', onClick: () => { void controller.execute({ action: 'account/sign-in', sessionRef, operationRef: operation.operationRef, scopes }); }, children: "\u53D1\u8D77\u8D26\u6237\u767B\u5F55" })] });
55
+ const enable = () => { void controller.execute({ action: 'operation/enable', operationRef: operation.operationRef, sessionRef, scopes: selected?.account ? scopes : [] }); };
56
+ return _jsxs("div", { className: "pap-operation", children: [_jsxs("div", { className: "pap-actions", children: [_jsxs("strong", { className: "pap-route", children: [operation.method, " ", operation.path] }), _jsx("span", { className: "pap-badge", children: operation.enabled ? '已允许 Agent 调用' : '未允许 Agent 调用' })] }), _jsxs("div", { className: "pap-actions", children: [!operation.enabled && _jsx("button", { disabled: busy || !selected, onClick: enable, children: "\u5141\u8BB8 Agent \u8C03\u7528" }), operation.enabled && _jsx("button", { disabled: busy, onClick: () => { void controller.execute({ action: 'operation/disable', operationRef: operation.operationRef }); }, children: "\u64A4\u9500\u64CD\u4F5C\u8BB8\u53EF" }), !selected && !operation.enabled && _jsx("span", { className: "pap-muted", children: "\u8BF7\u5148\u5EFA\u7ACB\u8FDE\u63A5" })] }), _jsxs("details", { children: [_jsx("summary", { children: "\u9AD8\u7EA7\uFF1A\u8FDE\u63A5\u4E0E\u8D26\u6237\u6743\u9650" }), _jsx("p", { className: "pap-muted", children: "\u4EC5\u5728\u9700\u8981\u66F4\u6362\u8FDE\u63A5\u6216\u767B\u5F55\u8D26\u6237\u65F6\u8BBE\u7F6E\u3002\u4E0B\u65B9\u9009\u62E9\u53EA\u5728\u660E\u786E\u4FDD\u5B58\u6388\u6743\u65F6\u751F\u6548\uFF0C\u4E0D\u8868\u793A\u5F53\u524D\u6388\u6743\u7684\u7ED1\u5B9A\u3002" }), _jsxs("label", { children: ["\u64CD\u4F5C\u8FDE\u63A5 ", _jsxs("select", { "aria-label": `连接 ${operation.method} ${operation.path}`, value: sessionRef, onChange: event => setSession(event.target.value), disabled: busy, children: [_jsx("option", { value: "", children: "\u9009\u62E9\u8FDE\u63A5" }), sessions.map(session => _jsxs("option", { value: session.sessionRef, children: [session.account ? '账户' : '未登录', " ", session.sessionRef.slice(-8)] }, session.sessionRef))] })] }), company.authMode === 'account' && _jsxs("div", { children: [!!company.scopes.length && _jsxs("div", { children: ["\u8D26\u6237\u6743\u9650 ", company.scopes.map(scope => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: scopes.includes(scope), disabled: busy, onChange: event => setScopes(event.target.checked ? [...scopes, scope] : scopes.filter(item => item !== scope)) }), scope] }, scope))] }), _jsx("button", { disabled: busy || !selected || scopes.length === 0, onClick: () => { void controller.execute({ action: 'account/sign-in', sessionRef, operationRef: operation.operationRef, scopes }); }, children: "\u53D1\u8D77\u8D26\u6237\u767B\u5F55" })] }), operation.enabled && _jsx("button", { disabled: busy || !selected, onClick: enable, children: "\u66F4\u65B0\u64CD\u4F5C\u8FDE\u63A5" })] })] });
28
57
  }
package/lib/tools.js CHANGED
@@ -14,15 +14,15 @@ export function apply(ctx) {
14
14
  const register = (tool) => { registry.register(tool); };
15
15
  const empty = { type: 'object', properties: {}, additionalProperties: false };
16
16
  const agent = (execution) => requirePap(execution.agent && !execution.signal?.aborted, 'permission_denied');
17
- register({ name: 'pap_status', description: 'Read PAP connection and account status. Ask the user to configure PAP or sign in when required.', parameters: empty, output,
17
+ register({ name: 'pap_status', description: 'Read PAP connection and account status. Ask the user to configure PAP or sign in when required. Example Service Agent: https://agent-network-protocol.com supports MCP, ANP and PAP. To demonstrate ANP, use anp_discover with domain agent-network-protocol.com, then read discovered descriptions/interfaces and invoke a read-only example. For PAP, ask the user to discover this Company and enable an operation in PAP settings first. MCP requires a configured server connection. Keep all identity approvals and user permissions.', parameters: empty, output,
18
18
  execute: async (_args, execution) => { agent(execution); return facade.status(); } });
19
19
  register({ name: 'pap_operations', description: 'List Company operations explicitly enabled by the user. Use their opaque operationRef with pap_request.', parameters: empty, output,
20
20
  execute: async (_args, execution) => { agent(execution); return facade.operations(); } });
21
- register({ name: 'pap_request', description: 'Invoke one user-enabled Company operation. Supply its operationRef and only declared path/query parameters and optional JSON body. Account sign-in is a separate user action.',
21
+ register({ name: 'pap_request', description: 'Invoke one user-enabled Company operation. Supply its operationRef and only declared path/query parameters and optional JSON body. Path and query values must be strings, including numeric parameters (for example query: {page: "1"}). Account sign-in is a separate user action.',
22
22
  parameters: { type: 'object', additionalProperties: false, required: ['operationRef'], properties: {
23
23
  operationRef: { type: 'string' },
24
- path: { type: 'object', additionalProperties: true },
25
- query: { type: 'object', additionalProperties: true },
24
+ path: { type: 'object', description: 'Declared path parameter values encoded as strings.', additionalProperties: { type: 'string', maxLength: 1024 } },
25
+ query: { type: 'object', description: 'Declared query parameter values encoded as strings; use page: "1", not page: 1.', additionalProperties: { type: 'string', maxLength: 4096 } },
26
26
  body: {},
27
27
  } }, output,
28
28
  execute: async (args, execution) => { agent(execution); return facade.request(args, execution.signal); } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awiki/dsh-pap",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Local-custody PAP 0.3 client for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -27,7 +27,8 @@
27
27
  "lib",
28
28
  "README.md",
29
29
  "cordis.patch.yml",
30
- "docs"
30
+ "docs",
31
+ "README.zh-CN.md"
31
32
  ],
32
33
  "scripts": {
33
34
  "build": "tsc -p tsconfig.json && node scripts/build-client.mjs",