@intra-mart/accel 0.3.0-dev.202606220635 → 0.3.0-dev.202606240810
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 +37 -0
- package/dist/commands/deploy.js +2 -1
- package/dist/commands/login.js +2 -1
- package/dist/i18n/en.js +2 -2
- package/dist/i18n/ja.js +2 -2
- package/dist/i18n/zh_CN.js +2 -2
- package/dist/interactive/credentials-prompts.js +3 -2
- package/dist/utils/mcp-sync.d.ts +4 -0
- package/dist/utils/mcp-sync.js +97 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -145,6 +145,7 @@ accel login
|
|
|
145
145
|
- `endpoint`(テキスト入力)と `apiKey`(マスク入力)を対話で入力します。
|
|
146
146
|
- 入力したトークンの有効性は、トークン検証API(`{endpoint}/oauth/token/verify`)を呼び出して確認します。検証に失敗(401 など)した場合や接続エラーの場合は、その場で再入力を促します。
|
|
147
147
|
- 検証に成功した時点で `.accel/credentials.json` に保存します。**APIキーはシークレットのため、ファイルは自動的に `.gitignore` に追加されます**(コミット対象外)。
|
|
148
|
+
- `.accel/credentials.json` の保存に成功すると、プロジェクト内の MCP 設定ファイルに対しても API キーを自動反映します(詳細は後述「[MCP 設定の自動同期](#mcp-設定の自動同期)」)。
|
|
148
149
|
|
|
149
150
|
#### 非対話モード
|
|
150
151
|
|
|
@@ -185,6 +186,7 @@ accel deploy
|
|
|
185
186
|
- 初回実行時に iAP の接続情報(エンドポイントURL・APIキー)の入力を求めます。入力値は `.accel/credentials.json` に保存され、保存値で接続できる限り次回以降は再入力不要です。事前に `accel login`(前述)で設定しておくこともできます。
|
|
186
187
|
- **APIキーはシークレット情報のため、`.accel/credentials.json` は自動的に `.gitignore` に追加されます**(コミット対象外)。
|
|
187
188
|
- デプロイ実行前に、トークン検証API(`/oauth/token/verify`)で接続情報の有効性を確認します。保存済みのエンドポイント/APIキーが誤っていて**接続エラーや認証エラー(401 など)になった場合は、その場で再入力を促し、接続できるまでリトライします**。中断したい場合は ESC / Ctrl+C で抜けられます。
|
|
189
|
+
- `.accel/credentials.json` に値を保存/更新したタイミングで、プロジェクト内の MCP 設定ファイルにも API キーを自動反映します(詳細は後述「[MCP 設定の自動同期](#mcp-設定の自動同期)」)。非対話モードでは `credentials.json` を保存しないため MCP 同期も発生しません。
|
|
188
190
|
- 既存のステージング環境を一覧から選択します(ステージングは iAP 側で事前に作成しておく必要があります)。
|
|
189
191
|
- デプロイ対象の zip は、`.accel/settings.json` の `artifactId` と `projectVersion` から `<artifactId>-<projectVersion>.zip` を `./target/` 配下で完全一致で特定し、見つかれば自動選択します。
|
|
190
192
|
- 該当ファイルが見つからない場合、または `.accel/settings.json` が無い場合は、従来通り `./target/` 配下の zip を一覧から選択します(単一なら自動選択)。
|
|
@@ -248,6 +250,39 @@ ACCEL_API_KEY=*** accel deploy \
|
|
|
248
250
|
|
|
249
251
|
`endpoint` には iAP のベースURL を指定します。API パス(`/api/bearer/development/...`)は CLI が組み立てます。
|
|
250
252
|
|
|
253
|
+
### MCP 設定の自動同期
|
|
254
|
+
|
|
255
|
+
`.accel/credentials.json` の保存に成功した直後、プロジェクト内のコーディングエージェント用 MCP 設定ファイルに対し iAP の API キーを `Authorization: Bearer <apiKey>` として自動反映します。
|
|
256
|
+
|
|
257
|
+
- 対象は `.accel/settings.json` の `agents` に含まれるエージェントのファイルだけです。
|
|
258
|
+
- **既存の MCP サーバーエントリのヘッダ値のみを更新**し、新規エントリの追加やファイル自体の新規作成は行いません(MCP 設定そのものは資材リポジトリ側で配備される前提)。
|
|
259
|
+
|
|
260
|
+
| エージェント | 対象ファイル | 更新箇所 |
|
|
261
|
+
|---|---|---|
|
|
262
|
+
| `claude-code` | `.mcp.json`(プロジェクトルート) | `mcpServers.<name>.headers.Authorization` |
|
|
263
|
+
| `codex` | `.codex/config.toml`(プロジェクトルート配下) | `[mcp_servers.<name>]` の `http_headers.Authorization`(`env_http_headers` 設定済みのエントリはスキップ) |
|
|
264
|
+
| `github-copilot` | `.vscode/mcp.json` | `servers.<name>.headers.Authorization` |
|
|
265
|
+
|
|
266
|
+
#### マッチング規則
|
|
267
|
+
|
|
268
|
+
各設定ファイル内で以下を全て満たす MCP サーバーエントリだけが更新対象になります:
|
|
269
|
+
|
|
270
|
+
- `type` が `"http"` である(Codex は TOML 形式上 `type` を持たないため、`url` キーが http(s) で始まることで判定)
|
|
271
|
+
- `url` が `credentials.json` の `endpoint` を**前方一致**で含む(例: `endpoint=https://example.com/imart` → `url=https://example.com/imart/im_logic` など)
|
|
272
|
+
|
|
273
|
+
該当エントリの `Authorization` キーのみが上書きされます。同じヘッダテーブル内の他のキーは保持されます。
|
|
274
|
+
|
|
275
|
+
#### 発動タイミング
|
|
276
|
+
|
|
277
|
+
- `accel login`(対話・非対話の両方、検証成功時)
|
|
278
|
+
- `accel deploy`(対話モードでの初回入力時/再入力ループの成功時)
|
|
279
|
+
- `accel deploy`(**非対話モード**)は `credentials.json` を保存しないため、MCP 同期も発生しません
|
|
280
|
+
|
|
281
|
+
#### エラー・ログ方針
|
|
282
|
+
|
|
283
|
+
- MCP 同期は best-effort で、いずれの段階で失敗してもコマンド自体の成否には影響しません。
|
|
284
|
+
- 対象ファイル/対象エントリが無い場合や処理に失敗した場合も**ログは表示しません**。
|
|
285
|
+
|
|
251
286
|
## IM-Juggling連携
|
|
252
287
|
|
|
253
288
|
`--juggling-project` オプションでIM-Jugglingプロジェクトのパスを指定すると、`juggling.im` からiAPバージョンと使用モジュールを自動検出します。
|
|
@@ -286,6 +321,8 @@ my-project/
|
|
|
286
321
|
- `.accel/hashsum.txt` — 配備ファイルのSHA-1。`detach` 時の変更検出に使用
|
|
287
322
|
- `.accel/credentials.json` — iAP接続情報(endpoint / APIキー)。`accel deploy` 初回実行時に生成。APIキーを含むため `.gitignore` 対象(git管理対象外)
|
|
288
323
|
|
|
324
|
+
`credentials.json` の保存/更新時には、エージェント別の MCP 設定ファイル(`.mcp.json` / `.codex/config.toml` / `.vscode/mcp.json` のうち、存在し、かつ `agents` に含まれるエージェントのもの)に対しても API キーが反映されます。詳細は「[MCP 設定の自動同期](#mcp-設定の自動同期)」を参照してください。
|
|
325
|
+
|
|
289
326
|
## 対応iAPバージョン
|
|
290
327
|
|
|
291
328
|
選択可能なiAPバージョン・モジュール・機能は、同梱のマスタデータパッケージ `@intra-mart/catalog` のカタログに基づきます(2025 Spring / 8.0.37 以降)。バージョンは `2026-spring` のようなリリースID形式で指定します。新しいリリースへの対応はカタログの更新によって行われます。
|
package/dist/commands/deploy.js
CHANGED
|
@@ -5,7 +5,8 @@ import { basename, resolve } from "node:path";
|
|
|
5
5
|
import { detectLocale } from "../utils/locale-detect.js";
|
|
6
6
|
import { formatEpochMillis } from "../utils/date-formatter.js";
|
|
7
7
|
import { readSettings, readSettingsSafe } from "../utils/settings-io.js";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveCredentialInputs } from "../utils/credentials.js";
|
|
9
|
+
import { persistCredentialsAndSyncMcp as defaultPersistCredentials } from "../utils/mcp-sync.js";
|
|
9
10
|
import { getMessage } from "../i18n/index.js";
|
|
10
11
|
import { lastFlagValue } from "../utils/args.js";
|
|
11
12
|
import { ensureCredentials as defaultEnsureCredentials, repromptCredentials as defaultRepromptCredentials, resolveCredentialsOrThrow as defaultResolveCredentialsOrThrow, } from "../interactive/credentials-prompts.js";
|
package/dist/commands/login.js
CHANGED
|
@@ -2,7 +2,8 @@ import { defineCommand } from "citty";
|
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
3
|
import { detectLocale } from "../utils/locale-detect.js";
|
|
4
4
|
import { readSettingsSafe } from "../utils/settings-io.js";
|
|
5
|
-
import { readCredentials as defaultReadCredentials,
|
|
5
|
+
import { readCredentials as defaultReadCredentials, resolveCredentialInputs, } from "../utils/credentials.js";
|
|
6
|
+
import { persistCredentialsAndSyncMcp as defaultPersistCredentials } from "../utils/mcp-sync.js";
|
|
6
7
|
import { repromptCredentials as defaultRepromptCredentials, resolveCredentialsOrThrow as defaultResolveCredentialsOrThrow, } from "../interactive/credentials-prompts.js";
|
|
7
8
|
import { verifyCredentialsLoop } from "../interactive/credential-auth.js";
|
|
8
9
|
import { createApiClient as defaultApiClientFactory, } from "../deploy/api-client.js";
|
package/dist/i18n/en.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const messages = {
|
|
2
|
-
"intro.init": "Generate an iAP (intra-mart Accel Platform) project and\nassets for Claude Code / GitHub Copilot.\nA few questions follow; everything is then deployed in one go.",
|
|
3
|
-
"intro.attach": "Mark the current directory as an iAP project and\ndeploy assets for Claude Code / GitHub Copilot.\nA few questions follow; everything is then deployed in one go.",
|
|
2
|
+
"intro.init": "Generate an iAP (intra-mart Accel Platform) project and\nassets for Claude Code / Codex / GitHub Copilot.\nA few questions follow; everything is then deployed in one go.",
|
|
3
|
+
"intro.attach": "Mark the current directory as an iAP project and\ndeploy assets for Claude Code / Codex / GitHub Copilot.\nA few questions follow; everything is then deployed in one go.",
|
|
4
4
|
"prompt.name": "Enter project name",
|
|
5
5
|
"prompt.name.hint": "Used as the directory name and recorded in pom.xml <name> and package.json name\nProvide a concise name that represents the system or feature you are creating (e.g. customer-portal, invoice-management)",
|
|
6
6
|
"prompt.artifactId": "Enter artifact ID (Maven artifactId)",
|
package/dist/i18n/ja.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const messages = {
|
|
2
|
-
"intro.init": "iAP(intra-mart Accel Platform)プロジェクトと、\nClaude Code / GitHub Copilot 向けの資材を生成します。\nいくつか質問した後、最後に一括で配備します。",
|
|
3
|
-
"intro.attach": "カレントディレクトリを iAP プロジェクトとして認識させ、\nClaude Code / GitHub Copilot 向けの資材を配備します。\nいくつか質問した後、最後に一括で配備します。",
|
|
2
|
+
"intro.init": "iAP(intra-mart Accel Platform)プロジェクトと、\nClaude Code / Codex / GitHub Copilot 向けの資材を生成します。\nいくつか質問した後、最後に一括で配備します。",
|
|
3
|
+
"intro.attach": "カレントディレクトリを iAP プロジェクトとして認識させ、\nClaude Code / Codex / GitHub Copilot 向けの資材を配備します。\nいくつか質問した後、最後に一括で配備します。",
|
|
4
4
|
"prompt.name": "プロジェクト名を入力してください",
|
|
5
5
|
"prompt.name.hint": "ディレクトリ名、pom.xml の <name>、package.json の name に反映されます\n作成するシステムや機能を端的に表す名称を指定してください(例: customer-portal, invoice-management)",
|
|
6
6
|
"prompt.artifactId": "アーティファクトID(pomのartifactId)を入力してください",
|
package/dist/i18n/zh_CN.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const messages = {
|
|
2
|
-
"intro.init": "生成 iAP(intra-mart Accel Platform)项目,\n以及面向 Claude Code / GitHub Copilot 的资源。\n将提出若干问题,最后统一进行部署。",
|
|
3
|
-
"intro.attach": "将当前目录识别为 iAP 项目,\n并部署面向 Claude Code / GitHub Copilot 的资源。\n将提出若干问题,最后统一进行部署。",
|
|
2
|
+
"intro.init": "生成 iAP(intra-mart Accel Platform)项目,\n以及面向 Claude Code / Codex / GitHub Copilot 的资源。\n将提出若干问题,最后统一进行部署。",
|
|
3
|
+
"intro.attach": "将当前目录识别为 iAP 项目,\n并部署面向 Claude Code / Codex / GitHub Copilot 的资源。\n将提出若干问题,最后统一进行部署。",
|
|
4
4
|
"prompt.name": "请输入项目名称",
|
|
5
5
|
"prompt.name.hint": "用作目录名称,并写入 pom.xml 的 <name> 和 package.json 的 name\n请提供能简洁表达所创建系统或功能的名称(例如: customer-portal, invoice-management)",
|
|
6
6
|
"prompt.artifactId": "请输入构件ID(Maven artifactId)",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import { readCredentials,
|
|
2
|
+
import { readCredentials, normalizeEndpoint } from "../utils/credentials.js";
|
|
3
|
+
import { persistCredentialsAndSyncMcp } from "../utils/mcp-sync.js";
|
|
3
4
|
import { getMessage } from "../i18n/index.js";
|
|
4
5
|
import { withHint } from "./format.js";
|
|
5
6
|
const requiredValidator = (locale) => (value) => !value || value.trim().length === 0
|
|
@@ -35,7 +36,7 @@ export const ensureCredentials = async (projectDir, locale, seed = {}) => {
|
|
|
35
36
|
apiKey,
|
|
36
37
|
};
|
|
37
38
|
if (changed) {
|
|
38
|
-
await
|
|
39
|
+
await persistCredentialsAndSyncMcp(projectDir, creds);
|
|
39
40
|
}
|
|
40
41
|
return creds;
|
|
41
42
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AccelCredentials } from "../core/types.js";
|
|
2
|
+
export declare const matchesEndpoint: (url: string, endpoint: string) => boolean;
|
|
3
|
+
export declare const syncMcpAuthorization: (projectDir: string, creds: AccelCredentials) => Promise<void>;
|
|
4
|
+
export declare const persistCredentialsAndSyncMcp: (projectDir: string, creds: AccelCredentials) => Promise<void>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
4
|
+
import { persistCredentials } from "./credentials.js";
|
|
5
|
+
import { readSettingsSafe } from "./settings-io.js";
|
|
6
|
+
const AUTHORIZATION_HEADER = "Authorization";
|
|
7
|
+
export const matchesEndpoint = (url, endpoint) => {
|
|
8
|
+
if (typeof url !== "string" || url.length === 0)
|
|
9
|
+
return false;
|
|
10
|
+
if (typeof endpoint !== "string" || endpoint.length === 0)
|
|
11
|
+
return false;
|
|
12
|
+
if (url === endpoint)
|
|
13
|
+
return true;
|
|
14
|
+
return url.startsWith(endpoint + "/");
|
|
15
|
+
};
|
|
16
|
+
const updateServers = (servers, endpoint, bearer, rules) => {
|
|
17
|
+
if (!servers || typeof servers !== "object")
|
|
18
|
+
return 0;
|
|
19
|
+
let updated = 0;
|
|
20
|
+
for (const value of Object.values(servers)) {
|
|
21
|
+
if (!value || typeof value !== "object")
|
|
22
|
+
continue;
|
|
23
|
+
const entry = value;
|
|
24
|
+
if (rules.requireHttpType && entry.type !== "http")
|
|
25
|
+
continue;
|
|
26
|
+
if (typeof entry.url !== "string")
|
|
27
|
+
continue;
|
|
28
|
+
if (!matchesEndpoint(entry.url, endpoint))
|
|
29
|
+
continue;
|
|
30
|
+
if (rules.shouldSkip?.(entry))
|
|
31
|
+
continue;
|
|
32
|
+
const existing = entry[rules.headersKey];
|
|
33
|
+
const headers = existing && typeof existing === "object"
|
|
34
|
+
? existing
|
|
35
|
+
: {};
|
|
36
|
+
headers[AUTHORIZATION_HEADER] = bearer;
|
|
37
|
+
entry[rules.headersKey] = headers;
|
|
38
|
+
updated++;
|
|
39
|
+
}
|
|
40
|
+
return updated;
|
|
41
|
+
};
|
|
42
|
+
const syncJsonFile = async (filePath, serversKey, endpoint, bearer) => {
|
|
43
|
+
try {
|
|
44
|
+
const content = await readFile(filePath, "utf-8");
|
|
45
|
+
const doc = JSON.parse(content);
|
|
46
|
+
const updated = updateServers(doc[serversKey], endpoint, bearer, {
|
|
47
|
+
headersKey: "headers",
|
|
48
|
+
requireHttpType: true,
|
|
49
|
+
});
|
|
50
|
+
if (updated > 0) {
|
|
51
|
+
await writeFile(filePath, JSON.stringify(doc, null, 2) + "\n", "utf-8");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const syncCodexToml = async (filePath, endpoint, bearer) => {
|
|
58
|
+
try {
|
|
59
|
+
const content = await readFile(filePath, "utf-8");
|
|
60
|
+
const doc = parseToml(content);
|
|
61
|
+
const updated = updateServers(doc.mcp_servers, endpoint, bearer, {
|
|
62
|
+
headersKey: "http_headers",
|
|
63
|
+
requireHttpType: false,
|
|
64
|
+
shouldSkip: (entry) => "env_http_headers" in entry,
|
|
65
|
+
});
|
|
66
|
+
if (updated > 0) {
|
|
67
|
+
const out = stringifyToml(doc);
|
|
68
|
+
await writeFile(filePath, out.endsWith("\n") ? out : out + "\n", "utf-8");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const syncMcpAuthorization = async (projectDir, creds) => {
|
|
75
|
+
const settings = await readSettingsSafe(projectDir);
|
|
76
|
+
if (!settings)
|
|
77
|
+
return;
|
|
78
|
+
const agents = settings.agents ?? [];
|
|
79
|
+
const bearer = `Bearer ${creds.apiKey}`;
|
|
80
|
+
if (agents.includes("claude-code")) {
|
|
81
|
+
await syncJsonFile(join(projectDir, ".mcp.json"), "mcpServers", creds.endpoint, bearer);
|
|
82
|
+
}
|
|
83
|
+
if (agents.includes("codex")) {
|
|
84
|
+
await syncCodexToml(join(projectDir, ".codex", "config.toml"), creds.endpoint, bearer);
|
|
85
|
+
}
|
|
86
|
+
if (agents.includes("github-copilot")) {
|
|
87
|
+
await syncJsonFile(join(projectDir, ".vscode", "mcp.json"), "servers", creds.endpoint, bearer);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
export const persistCredentialsAndSyncMcp = async (projectDir, creds) => {
|
|
91
|
+
await persistCredentials(projectDir, creds);
|
|
92
|
+
try {
|
|
93
|
+
await syncMcpAuthorization(projectDir, creds);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
}
|
|
97
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intra-mart/accel",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.202606240810",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tool for intra-mart Accel Platform development",
|
|
6
6
|
"author": "NTT DATA INTRAMART",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"remark-parse": "^11.0.0",
|
|
47
47
|
"remark-stringify": "^11.0.0",
|
|
48
48
|
"semver": "^7.7.1",
|
|
49
|
+
"smol-toml": "^1.6.1",
|
|
49
50
|
"tar": "^7.4.3",
|
|
50
51
|
"unified": "^11.0.5",
|
|
51
52
|
"unist-util-visit": "^5.0.0"
|