@vess-id/ai-identity 0.15.0 → 0.15.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/dist/index.mjs CHANGED
@@ -5309,6 +5309,34 @@ var ACTION_REGISTRY = {
5309
5309
  },
5310
5310
  version: "1.0.0"
5311
5311
  },
5312
+ {
5313
+ // AIDENTITY-66: delete a comment from a Jira issue. high-risk destructive
5314
+ // write — mirrors jira.issue.delete (admin/owner/act_as) but resource_type
5315
+ // は jira.comment.create と同じ jira:project (issue から project を derive)。
5316
+ action: "jira.comment.delete",
5317
+ resource_type: "jira:project",
5318
+ required_relations: ["admin", "owner", "act_as"],
5319
+ required_scopes: ["write:jira-work"],
5320
+ capability: "jira.write.basic",
5321
+ input_schema: {
5322
+ type: "object",
5323
+ properties: {
5324
+ issueIdOrKey: { type: "string", minLength: 1 },
5325
+ commentId: { type: "string", minLength: 1, description: "Comment id (from jira.comment.read)" }
5326
+ },
5327
+ required: ["issueIdOrKey", "commentId"],
5328
+ additionalProperties: false
5329
+ },
5330
+ constraints: { rate_bucket: "jira.write" },
5331
+ effects: ["Delete:Comment"],
5332
+ // high: deleting a comment is irreversible and visible to all project members,
5333
+ // consistent with jira.issue.delete / jira.comment.create.
5334
+ risk: "high",
5335
+ target_bindings: {
5336
+ resource_id: { source: "param", param: "issueIdOrKey", fallback_param: "issueKey", derive: "project_key" }
5337
+ },
5338
+ version: "1.0.0"
5339
+ },
5312
5340
  {
5313
5341
  action: "jira.comment.read",
5314
5342
  resource_type: "jira:project",
@@ -5474,6 +5502,42 @@ var ACTION_REGISTRY = {
5474
5502
  },
5475
5503
  version: "1.0.0"
5476
5504
  },
5505
+ {
5506
+ // AIDENTITY-83: email / displayName から accountId を解決する read action。
5507
+ // query は resource id ではなく検索語なので target_bindings は付けず
5508
+ // (jira.project.read 等の unscoped read と同様)、type-only match で評価する。
5509
+ action: "jira.user.search",
5510
+ resource_type: "jira:user",
5511
+ required_relations: ["viewer", "editor", "admin", "owner"],
5512
+ required_scopes: ["read:jira-user"],
5513
+ capability: "jira.read.basic",
5514
+ input_schema: {
5515
+ type: "object",
5516
+ properties: {
5517
+ query: {
5518
+ type: "string",
5519
+ minLength: 1,
5520
+ description: "Matched against displayName and emailAddress (prefix match). Pass an email address to resolve its accountId."
5521
+ },
5522
+ maxResults: {
5523
+ type: "integer",
5524
+ minimum: 1,
5525
+ maximum: 50,
5526
+ description: "Max users to return (default 10)"
5527
+ }
5528
+ },
5529
+ required: ["query"],
5530
+ additionalProperties: false
5531
+ },
5532
+ constraints: { rate_bucket: "jira.read" },
5533
+ effects: ["Read:User"],
5534
+ risk: "low",
5535
+ // query は resource id ではないので unscoped。required: false で type-only match。
5536
+ target_bindings: {
5537
+ resource_id: { source: "param", param: "query", required: false }
5538
+ },
5539
+ version: "1.0.0"
5540
+ },
5477
5541
  // ─── OS Actions (Local) ───
5478
5542
  {
5479
5543
  action: "os.secret.read",
@@ -6269,14 +6333,14 @@ var ACTION_REGISTRY = {
6269
6333
  },
6270
6334
  {
6271
6335
  capability: "jira.read.basic",
6272
- description: "Read Jira issues, projects, boards, sprints, and issue link types",
6273
- includes: ["jira.project.read", "jira.board.read", "jira.sprint.read", "jira.issue.list", "jira.issue.search", "jira.worklog.read", "jira.issue.read", "jira.batch.read", "jira.comment.read", "jira.transition.list", "jira.issuelinktype.list"],
6336
+ description: "Read Jira issues, projects, boards, sprints, issue link types, and users",
6337
+ includes: ["jira.project.read", "jira.board.read", "jira.sprint.read", "jira.issue.list", "jira.issue.search", "jira.worklog.read", "jira.issue.read", "jira.batch.read", "jira.comment.read", "jira.transition.list", "jira.issuelinktype.list", "jira.user.search"],
6274
6338
  version: "1.0.0"
6275
6339
  },
6276
6340
  {
6277
6341
  capability: "jira.write.basic",
6278
- description: "Create, update, delete Jira issues, and manage issue links",
6279
- includes: ["jira.issue.create", "jira.issue.update", "jira.issue.delete", "jira.comment.create", "jira.issue.transition", "jira.issuelink.create", "jira.issuelink.delete"],
6342
+ description: "Create, update, delete Jira issues, manage issue links, and add/delete comments",
6343
+ includes: ["jira.issue.create", "jira.issue.update", "jira.issue.delete", "jira.comment.create", "jira.comment.delete", "jira.issue.transition", "jira.issuelink.create", "jira.issuelink.delete"],
6280
6344
  version: "1.0.0"
6281
6345
  },
6282
6346
  {
@@ -6697,7 +6761,7 @@ var ACTION_DISPLAY_CONFIGS = {
6697
6761
  summaryTemplate: (p) => {
6698
6762
  const parts = [];
6699
6763
  if (p.summary) parts.push(p.summary);
6700
- if (p.start) parts.push(`(${formatValue(p.start)})`);
6764
+ if (p.start) parts.push(`(${formatCalendarTime(p.start)})`);
6701
6765
  return parts.join(" ");
6702
6766
  },
6703
6767
  displayFields: [
@@ -6711,7 +6775,7 @@ var ACTION_DISPLAY_CONFIGS = {
6711
6775
  summaryTemplate: (p) => {
6712
6776
  const parts = [];
6713
6777
  if (p.summary) parts.push(p.summary);
6714
- if (p.start) parts.push(`(${formatValue(p.start)})`);
6778
+ if (p.start) parts.push(`(${formatCalendarTime(p.start)})`);
6715
6779
  return parts.join(" ");
6716
6780
  },
6717
6781
  displayFields: [
@@ -6801,7 +6865,7 @@ var ACTION_DISPLAY_CONFIGS = {
6801
6865
  ]
6802
6866
  },
6803
6867
  // AIDENTITY-65: comment 本体は string と ADF document の両方を受けるため、
6804
- // formatValue 側の ADF ハンドリング (extractFirstAdfText) に任せて key 指定で OK。
6868
+ // detail 表示の ADF 描画は formatValueFull 側に任せて key 指定で OK。
6805
6869
  "jira.comment.create": {
6806
6870
  summaryTemplate: (p) => {
6807
6871
  const parts = [];
@@ -6814,6 +6878,21 @@ var ACTION_DISPLAY_CONFIGS = {
6814
6878
  { key: "body", label: "Comment" }
6815
6879
  ]
6816
6880
  },
6881
+ // AIDENTITY-66: 破壊的操作なので「どの issue のどの comment を消すか」を明示する
6882
+ // (jira.issue.delete / jira.issuelink.delete と同じ destructive 表現の方針)。
6883
+ "jira.comment.delete": {
6884
+ summaryTemplate: (p) => {
6885
+ const issue = p.issueIdOrKey ?? p.issueKey;
6886
+ const commentId = p.commentId ?? p.id;
6887
+ if (issue && commentId) return `Delete comment ${commentId} on ${issue}`;
6888
+ if (commentId) return `Delete comment ${commentId}`;
6889
+ return "";
6890
+ },
6891
+ displayFields: [
6892
+ { label: "Issue", extract: (p) => p.issueIdOrKey ?? p.issueKey },
6893
+ { label: "Comment", extract: (p) => p.commentId ?? p.id }
6894
+ ]
6895
+ },
6817
6896
  // AIDENTITY-65: API enricher が 'Link' label を upsert で書き換える。
6818
6897
  "jira.issuelink.delete": {
6819
6898
  summaryTemplate: (p) => {
@@ -6825,6 +6904,17 @@ var ACTION_DISPLAY_CONFIGS = {
6825
6904
  { key: "linkId", label: "Link" }
6826
6905
  ]
6827
6906
  },
6907
+ // AIDENTITY-83: email / displayName から accountId を解決する read action。
6908
+ "jira.user.search": {
6909
+ summaryTemplate: (p) => {
6910
+ if (p.query) return `Search users: ${String(p.query)}`;
6911
+ return "";
6912
+ },
6913
+ displayFields: [
6914
+ { key: "query", label: "Query" },
6915
+ { key: "maxResults", label: "Max Results" }
6916
+ ]
6917
+ },
6828
6918
  // ─── Agent Inbox ───
6829
6919
  "inbox.send": {
6830
6920
  summaryTemplate: (p) => {
@@ -6880,18 +6970,32 @@ function truncate(text, maxLength) {
6880
6970
  if (text.length <= maxLength) return text;
6881
6971
  return text.slice(0, maxLength - 3) + "...";
6882
6972
  }
6883
- function formatValue(value) {
6973
+ function formatCalendarTime(value) {
6974
+ if (value && typeof value === "object" && !Array.isArray(value)) {
6975
+ const obj = value;
6976
+ if (obj.dateTime) {
6977
+ return obj.timeZone ? `${obj.dateTime} (${obj.timeZone})` : String(obj.dateTime);
6978
+ }
6979
+ if (obj.date) return String(obj.date);
6980
+ }
6981
+ return String(value);
6982
+ }
6983
+ function formatValueFull(value) {
6884
6984
  if (value === void 0) return "";
6885
6985
  if (value === null) return "(unset)";
6886
6986
  if (Array.isArray(value)) {
6887
- return value.map((item) => {
6987
+ const parts = value.map((item) => {
6888
6988
  if (item && typeof item === "object") {
6889
6989
  const email = item.email;
6890
6990
  if (email) return String(email);
6891
- return JSON.stringify(item);
6991
+ return JSON.stringify(item, null, 2);
6892
6992
  }
6893
6993
  return String(item);
6894
- }).join(", ");
6994
+ });
6995
+ const hasMultiline = parts.some((p) => p.includes("\n"));
6996
+ const joinedShort = parts.join(", ");
6997
+ if (hasMultiline || joinedShort.length > 80) return parts.join("\n");
6998
+ return joinedShort;
6895
6999
  }
6896
7000
  if (typeof value === "object") {
6897
7001
  const obj = value;
@@ -6900,33 +7004,118 @@ function formatValue(value) {
6900
7004
  }
6901
7005
  if (obj.date) return String(obj.date);
6902
7006
  if (obj.type === "doc" && Array.isArray(obj.content)) {
6903
- const firstText = extractFirstAdfText(obj.content);
6904
- if (firstText) {
6905
- const moreCount = obj.content.length - 1;
6906
- const more = moreCount > 0 ? ` \u2026 (+${moreCount} block${moreCount > 1 ? "s" : ""})` : "";
6907
- return `${firstText}${more}`;
6908
- }
6909
- return "(ADF document)";
7007
+ const rendered = renderAdfDocument(obj.content).trim();
7008
+ if (rendered) return rendered;
7009
+ if (obj.content.length > 0) return JSON.stringify(value, null, 2);
7010
+ return "";
6910
7011
  }
6911
- return JSON.stringify(value);
7012
+ return JSON.stringify(value, null, 2);
6912
7013
  }
6913
7014
  return String(value);
6914
7015
  }
6915
- function extractFirstAdfText(nodes) {
7016
+ function renderAdfDocument(nodes, indent = "") {
7017
+ const lines = [];
6916
7018
  for (const node of nodes) {
6917
7019
  if (!node || typeof node !== "object") continue;
6918
7020
  const n = node;
6919
- if (n.type === "paragraph" || n.type === "heading") {
6920
- const inner = n.content ?? [];
6921
- for (const child of inner) {
6922
- if (child && typeof child === "object") {
6923
- const c = child;
6924
- if (c.type === "text" && typeof c.text === "string") return c.text;
7021
+ const type = n.type;
7022
+ const content = n.content ?? [];
7023
+ switch (type) {
7024
+ case "paragraph": {
7025
+ lines.push(indent + renderAdfInline(content));
7026
+ break;
7027
+ }
7028
+ case "heading": {
7029
+ const level = Number(n.attrs?.level) || 1;
7030
+ lines.push(indent + "#".repeat(level) + " " + renderAdfInline(content));
7031
+ break;
7032
+ }
7033
+ case "bulletList":
7034
+ case "orderedList": {
7035
+ const ordered = type === "orderedList";
7036
+ let orderedCounter = 0;
7037
+ content.forEach((item) => {
7038
+ if (!item || typeof item !== "object") return;
7039
+ const li = item;
7040
+ const liContent = li.content ?? [];
7041
+ orderedCounter++;
7042
+ const marker = ordered ? `${orderedCounter}. ` : "- ";
7043
+ const inner = renderAdfDocument(liContent, indent + " ");
7044
+ const innerLines = inner.split("\n");
7045
+ const firstTrimmed = innerLines.length > 0 ? innerLines[0].slice((indent + " ").length) : "";
7046
+ lines.push(indent + marker + firstTrimmed);
7047
+ for (let i = 1; i < innerLines.length; i++) lines.push(innerLines[i]);
7048
+ });
7049
+ break;
7050
+ }
7051
+ case "codeBlock": {
7052
+ lines.push(indent + renderAdfInline(content));
7053
+ break;
7054
+ }
7055
+ case "blockquote": {
7056
+ const inner = renderAdfDocument(content, indent);
7057
+ if (inner) {
7058
+ for (const l of inner.split("\n")) lines.push(indent + "> " + l.slice(indent.length));
6925
7059
  }
7060
+ break;
7061
+ }
7062
+ case "panel": {
7063
+ const panelType = n.attrs?.panelType;
7064
+ if (panelType) lines.push(indent + `[panel:${String(panelType)}]`);
7065
+ const panelInner = renderAdfDocument(content, indent);
7066
+ if (panelInner) lines.push(panelInner);
7067
+ break;
7068
+ }
7069
+ case "rule": {
7070
+ lines.push(indent + "---");
7071
+ break;
7072
+ }
7073
+ default: {
7074
+ if (content.length > 0) {
7075
+ const inner = renderAdfDocument(content, indent);
7076
+ if (inner) lines.push(inner);
7077
+ } else {
7078
+ const inline = renderAdfInline([n]);
7079
+ if (inline) lines.push(indent + inline);
7080
+ }
7081
+ break;
6926
7082
  }
6927
7083
  }
6928
7084
  }
6929
- return "";
7085
+ return lines.join("\n");
7086
+ }
7087
+ function renderAdfInline(nodes) {
7088
+ let out = "";
7089
+ for (const node of nodes) {
7090
+ if (!node || typeof node !== "object") continue;
7091
+ const n = node;
7092
+ const attrs = n.attrs ?? {};
7093
+ switch (n.type) {
7094
+ case "text":
7095
+ if (typeof n.text === "string") out += n.text;
7096
+ break;
7097
+ case "hardBreak":
7098
+ out += "\n";
7099
+ break;
7100
+ case "mention":
7101
+ out += String(attrs.text ?? attrs.id ?? "@mention");
7102
+ break;
7103
+ case "emoji":
7104
+ out += String(attrs.text ?? attrs.shortName ?? "");
7105
+ break;
7106
+ case "inlineCard":
7107
+ out += String(attrs.url ?? "");
7108
+ break;
7109
+ default:
7110
+ if (Array.isArray(n.content)) {
7111
+ out += renderAdfInline(n.content);
7112
+ } else if (typeof attrs.text === "string") {
7113
+ out += attrs.text;
7114
+ }
7115
+ break;
7116
+ }
7117
+ }
7118
+ return out;
6930
7119
  }
6931
7120
  var ACTION_PARAMS_MAX_SIZE = 1e4;
6932
7121
  function generateActionSummary(action, params, maxLength = 50) {
@@ -6950,11 +7139,11 @@ function generateActionParamsDisplay(action, params) {
6950
7139
  return config.displayFields.map((f) => {
6951
7140
  const raw = f.extract ? f.extract(params) : f.key ? params[f.key] : void 0;
6952
7141
  return { label: f.label, raw };
6953
- }).filter((item) => item.raw !== void 0).map((item) => ({ label: item.label, value: formatValue(item.raw) }));
7142
+ }).filter((item) => item.raw !== void 0).map((item) => ({ label: item.label, value: formatValueFull(item.raw) }));
6954
7143
  }
6955
- return Object.entries(params).filter(([, v]) => v !== void 0 && v !== null).slice(0, 3).map(([key, val]) => ({
7144
+ return Object.entries(params).filter(([, v]) => v !== void 0 && v !== null).map(([key, val]) => ({
6956
7145
  label: key,
6957
- value: formatValue(val)
7146
+ value: formatValueFull(val)
6958
7147
  }));
6959
7148
  }
6960
7149