@bash0816/copilot-termux 1.0.69 → 1.0.70

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.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "manifest_version": 1,
3
3
  "package_name": "@bash0816/copilot-termux",
4
- "copilot_version": "1.0.69",
5
- "latest_audited_version": "1.0.68-1",
4
+ "copilot_version": "1.0.70",
5
+ "latest_audited_version": "1.0.69",
6
6
  "latest_candidate_version": null,
7
- "previous_stable_version": "1.0.68",
7
+ "previous_stable_version": "1.0.68-1",
8
8
  "candidate_state": "none",
9
9
  "canonical_package_status": "not_published",
10
10
  "public_distribution_status": "staged",
11
11
  "nodejs_glibc_version": "node-glibc-v24.15.0",
12
12
  "build_run_id": null,
13
- "last_updated": "2026-07-07",
13
+ "last_updated": "2026-07-10",
14
14
  "manifest_url": "https://raw.githubusercontent.com/bash0816/Github-Copilot-Termux/main/packages/copilot-termux/config/copilot-termux-release-manifest.json"
15
15
  }
@@ -2,8 +2,8 @@
2
2
  "wrapperVersion": "2.0.0",
3
3
  "copilot": {
4
4
  "package": "@github/copilot-linuxmusl-arm64",
5
- "version": "1.0.69",
6
- "integrity": "sha512-Y6DY9RkyWV6l+S0cNz4d+AkUa38goNV5StQH3j8OoVrndK3+RgQeUjG1XpJ//PzXEXi4vQ0cZuc9XzFj/TY7tw=="
5
+ "version": "1.0.70",
6
+ "integrity": "sha512-Xy3tDjIMmMkZZzJjCrK5aDCLLV5+pyOfIcT1lWLmqVWJG0erpHXL6KU82nGW+0nc0TPqGZFHvOyQeLuXl+s3ZA=="
7
7
  },
8
8
  "glibcNode": {
9
9
  "version": "26.2.0",
@@ -18,6 +18,33 @@ if (process.report) {
18
18
  const Module = require('module');
19
19
  const fs = require('fs');
20
20
  const path = require('path');
21
+ const { execFile } = require('child_process');
22
+ const { promisify } = require('util');
23
+ const execFileAsync = promisify(execFile);
24
+
25
+ // git CLIを配列引数で呼ぶ(shell経由なし、インジェクション対策)。失敗時は例外を投げず安全な既定値を返す。
26
+ async function runGit(cwd, args) {
27
+ try {
28
+ const { stdout } = await execFileAsync('git', args, { cwd, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
29
+ return stdout;
30
+ } catch (_) {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ // backupFile() は戻り値を `${r.substring(9,25)}-${Date.now()}` としてバックアップファイル名に使う。
36
+ // substring(9,25) は "git-sha1:" (9文字) プレフィックスを除いた先頭16文字を取る計算であり、
37
+ // ネイティブ実装の実際の戻り値フォーマットが "git-sha1:<40hex>" であることを示している。
38
+ // 互換性のため git hash-object 相当(blob SHA1)を "git-sha1:" プレフィックス付きで返す。
39
+ async function hashFileContent(gitRoot, filePath) {
40
+ try {
41
+ const out = await runGit(gitRoot, ['hash-object', '--', filePath]);
42
+ if (!out) return null;
43
+ return `git-sha1:${out.trim()}`;
44
+ } catch (_) {
45
+ return null;
46
+ }
47
+ }
21
48
 
22
49
  const _pkgVersion = (() => {
23
50
  try { return require(path.join(__dirname, '..', 'package.json')).version; } catch (_) { return '1.0.65'; }
@@ -76,6 +103,7 @@ Module._load = function (request, parent, isMain) {
76
103
  path.basename(request) === 'runtime.node') {
77
104
  if (result.__copilotTermuxPatched) return result;
78
105
  result.__copilotTermuxPatched = true;
106
+ let _nfIdSeq = 3e6;
79
107
  const isGlibcMode = !!process.env.COPILOT_TERMUX_GLIBC_MODE;
80
108
  if (!isGlibcMode) {
81
109
  // Rust tokio を使う関数群を no-op に差し替え。
@@ -84,12 +112,29 @@ Module._load = function (request, parent, isMain) {
84
112
  // jsonrpcServer* は拡張 JSON-RPC サーバー (ThreadsafeFunction)、
85
113
  // lspClient* は LSP クライアント (ThreadsafeFunction)。
86
114
  // featureFlagService* は同期 Rust のため除外(no-op にすると .handle クラッシュ)。
87
- const TOKIO_PATTERN = /^(ahpRelay|ahpRelayAuthenticate|ahpRelayCancelTurn|ahpRelayCompleteInput|ahpRelayCompletions|ahpRelayConfirmToolCall|ahpRelayConnect|ahpRelayCreate|ahpRelayCreateSession|ahpRelayDispose|ahpRelayGetPlan|ahpRelayListCheckpoints|ahpRelayListWorkspaceFiles|ahpRelayPendingRequiredResourcesJson|ahpRelayReadCheckpoint|ahpRelayRefreshSessions|ahpRelayReleaseSession|ahpRelayRemovePendingMessage|ahpRelaySelectAgent|ahpRelaySessionDiff|ahpRelaySetMode|ahpRelaySetModel|ahpRelaySetPendingMessage|ahpRelaySetSessionApproveAll|ahpRelaySetTitle|ahpRelayStartTurn|ahpRelayStateJson|ahpRelaySubscribeSession|ahpRelayTerminalDispose|ahpRelayTerminalEnsure|ahpRelayTerminalWrite|jsonrpcServer|jsonrpcServerAddConnection|jsonrpcServerBeginShutdown|jsonrpcServerConnectionClose|jsonrpcServerConnectionNotify|jsonrpcServerConnectionNotifyAfterResponse|jsonrpcServerConnectionRequest|jsonrpcServerConnectionWrite|jsonrpcServerCreate|jsonrpcServerDispatchComplete|jsonrpcServerRegisterSession|jsonrpcServerRemove|jsonrpcServerRemoveSession|jsonrpcServerStartTcpListener|jsonrpcServerStopTcpListener|lspClient|lspClientCloseDocument|lspClientCreateOwned|lspClientCreateOwnedSandboxed|lspClientDispose|lspClientEnhanceStartupErrorMessage|lspClientFindSourceFile|lspClientInitialize|lspClientInitialized|lspClientOpenDocument|lspClientOwnedShutdown|lspClientRequest|lspClientTakeExitInfo|lspClientWaitForDiagnostics|lspClientWaitForProjectLoad|modelHttp|modelHttpCancelRequest|modelHttpRegisterCancellation|modelHttpResetNetworking|networkFetch|networkFetchNextRequestId|networkFetchResetClients|sessionSqlite|sessionSqliteClose|sessionSqliteExec|sessionStore|sessionStoreBeginForgeSkillProposalGeneration|sessionStoreClose|sessionStoreCompleteForgeSkillProposalGeneration|sessionStoreDefaultPath|sessionStoreDeleteDynamicContextItem|sessionStoreEnsureSession|sessionStoreExec|sessionStoreExecuteReadOnly|sessionStoreExecuteReadOnlyAsync|sessionStoreFailStaleGeneratingForgeSkillProposals|sessionStoreGetCheckpoints|sessionStoreGetDynamicContextBoard|sessionStoreGetDynamicContextItem|sessionStoreGetFiles|sessionStoreGetForgeSkillProposalByFingerprint|sessionStoreGetForgeSkillProposalById|sessionStoreGetForgeSkillProposalWorkspaceBefore|sessionStoreGetForgeTrajectoryEvents|sessionStoreGetForgeTrajectoryEventsForScope|sessionStoreGetMaxTurnIndex|sessionStoreGetRefs|sessionStoreGetSession|sessionStoreGetStats|sessionStoreGetTurns|sessionStoreIncrementDynamicContextCount|sessionStoreIncrementDynamicContextReadCount|sessionStoreIndexWorkspaceArtifact|sessionStoreInsertAssistantUsageEventWithRuntimeDefaults|sessionStoreInsertCheckpointWithRuntimeDefaults|sessionStoreInsertDynamicContextItem|sessionStoreInsertFileWithRuntimeDefaults|sessionStoreInsertForgeTrajectoryEventWithRuntimeDefaults|sessionStoreInsertRefWithRuntimeDefaults|sessionStoreInsertTurnWithRuntimeDefaults|sessionStoreListForgeSkillProposals|sessionStoreOpen|sessionStoreSearch|sessionStoreTrackingEventOperations|sessionStoreTrackingExtractFilePath|sessionStoreTrackingExtractForgeTrajectoryEvents|sessionStoreTrackingExtractRefsFromBash|sessionStoreTrackingExtractRefsFromMcpTool|sessionStoreTrackingExtractRepoFromMcpTool|sessionStoreTrackingFlushOperations|sessionStoreTrackingInitialState|sessionStoreTransitionForgeSkillProposalStatus|sessionStoreUpsertDynamicContextItem|sessionStoreUpsertSessionWithRuntimeDefaults|websocketResponses)/;
115
+ const TOKIO_PATTERN = /^(ahpRelay|ahpRelayAuthenticate|ahpRelayCancelTurn|ahpRelayCompleteInput|ahpRelayCompletions|ahpRelayConfirmToolCall|ahpRelayConnect|ahpRelayCreate|ahpRelayCreateSession|ahpRelayDispose|ahpRelayGetPlan|ahpRelayListCheckpoints|ahpRelayListWorkspaceFiles|ahpRelayPendingRequiredResourcesJson|ahpRelayReadCheckpoint|ahpRelayRefreshSessions|ahpRelayReleaseSession|ahpRelayRemovePendingMessage|ahpRelaySelectAgent|ahpRelaySessionDiff|ahpRelaySetMode|ahpRelaySetModel|ahpRelaySetPendingMessage|ahpRelaySetSessionApproveAll|ahpRelaySetTitle|ahpRelayStartTurn|ahpRelayStateJson|ahpRelaySubscribeSession|ahpRelayTerminalDispose|ahpRelayTerminalEnsure|ahpRelayTerminalWrite|jsonrpcServer|jsonrpcServerAddConnection|jsonrpcServerBeginShutdown|jsonrpcServerConnectionClose|jsonrpcServerConnectionNotify|jsonrpcServerConnectionNotifyAfterResponse|jsonrpcServerConnectionRequest|jsonrpcServerConnectionWrite|jsonrpcServerCreate|jsonrpcServerDispatchComplete|jsonrpcServerRegisterSession|jsonrpcServerRemove|jsonrpcServerRemoveSession|jsonrpcServerStartTcpListener|jsonrpcServerStopTcpListener|lspClient|lspClientCloseDocument|lspClientCreateOwned|lspClientCreateOwnedSandboxed|lspClientDispose|lspClientEnhanceStartupErrorMessage|lspClientFindSourceFile|lspClientInitialize|lspClientInitialized|lspClientOpenDocument|lspClientOwnedShutdown|lspClientRequest|lspClientTakeExitInfo|lspClientWaitForDiagnostics|lspClientWaitForProjectLoad|modelHttp|modelHttpCancelRequest|modelHttpRegisterCancellation|modelHttpResetNetworking|networkFetch|networkFetchNextRequestId|networkFetchResetClients|sessionSqlite|sessionSqliteClose|sessionSqliteExec|sessionStore|sessionStoreBeginForgeSkillProposalGeneration|sessionStoreClose|sessionStoreCompleteForgeSkillProposalGeneration|sessionStoreDefaultPath|sessionStoreDeleteDynamicContextItem|sessionStoreEnsureSession|sessionStoreExec|sessionStoreExecuteReadOnly|sessionStoreExecuteReadOnlyAsync|sessionStoreExecuteReadOnlyWithCap|sessionStoreFailStaleGeneratingForgeSkillProposals|sessionStoreGetCheckpoints|sessionStoreGetDynamicContextBoard|sessionStoreGetDynamicContextItem|sessionStoreGetFiles|sessionStoreGetForgeSkillProposalByFingerprint|sessionStoreGetForgeSkillProposalById|sessionStoreGetForgeSkillProposalWorkspaceBefore|sessionStoreGetForgeTrajectoryEvents|sessionStoreGetForgeTrajectoryEventsForScope|sessionStoreGetMaxTurnIndex|sessionStoreGetRefs|sessionStoreGetSession|sessionStoreGetStats|sessionStoreGetTurns|sessionStoreIncrementDynamicContextCount|sessionStoreIncrementDynamicContextReadCount|sessionStoreIndexWorkspaceArtifact|sessionStoreInsertAssistantUsageEventWithRuntimeDefaults|sessionStoreInsertCheckpointWithRuntimeDefaults|sessionStoreInsertDynamicContextItem|sessionStoreInsertFileWithRuntimeDefaults|sessionStoreInsertForgeTrajectoryEventWithRuntimeDefaults|sessionStoreInsertRefWithRuntimeDefaults|sessionStoreInsertTurnWithRuntimeDefaults|sessionStoreListForgeSkillProposals|sessionStoreOpen|sessionStoreSearch|sessionStoreTrackingEventOperations|sessionStoreTrackingExtractFilePath|sessionStoreTrackingExtractForgeTrajectoryEvents|sessionStoreTrackingExtractRefsFromBash|sessionStoreTrackingExtractRefsFromMcpTool|sessionStoreTrackingExtractRepoFromMcpTool|sessionStoreTrackingFlushOperations|sessionStoreTrackingInitialState|sessionStoreTransitionForgeSkillProposalStatus|sessionStoreUpsertDynamicContextItem|sessionStoreUpsertSessionWithRuntimeDefaults|websocketResponses)/;
88
116
  for (const key of Object.keys(result)) {
89
117
  if (TOKIO_PATTERN.test(key) && typeof result[key] === 'function') {
90
118
  result[key] = () => undefined;
91
119
  }
92
120
  }
121
+ // networkFetchNextRequestId は networkFetchStreamStart/RequestCancel の相関キーとして
122
+ // 実際に使われるため、no-opのままにはできない。TOKIO_PATTERNの一括no-op化で
123
+ // 潰された直後にJSの単調増加ID生成で上書きする。
124
+ result.networkFetchNextRequestId = () => 'nf-' + (++_nfIdSeq);
125
+ // MCP-BIONIC-001: 実機でSIGSEGV確認済みの2関数を、bionicモード限定でクリーンエラー化する。
126
+ // 対象外の残り10関数はdocs/KNOWN-BUGS.mdのMCP-BIONIC-001セクションに未検証事項として個別記録済み。
127
+ const BIONIC_SIGSEGV_STUBS = [
128
+ 'capiClientRetrieveAvailableModels',
129
+ 'mcpClientConnectStreamableHttpWithHandlersAndOnclose',
130
+ ];
131
+ for (const _key of BIONIC_SIGSEGV_STUBS) {
132
+ if (typeof result[_key] === 'function') {
133
+ result[_key] = () => {
134
+ throw new Error(`${_key} unsupported on Android bionic (native tokio disabled to avoid SIGSEGV)`);
135
+ };
136
+ }
137
+ }
93
138
  // git*Async: Rust tokio async functions — type-safe stubs to prevent SIGSEGV.
94
139
  // Returns empty/null values matching what app.js callers expect.
95
140
  const GIT_ASYNC_STUBS = {
@@ -112,6 +157,58 @@ Module._load = function (request, parent, isMain) {
112
157
  gitStatusPorcelainAllAsync: async () => null,
113
158
  gitCurrentBranchRemoteAsync: async () => null,
114
159
  gitWorkingTreeDiffStatsAsync: async () => ({ linesAdded: 0, linesRemoved: 0 }),
160
+ gitFindRootWithOptionalWorktreeResolutionAsync: async (cwd) => {
161
+ const out = await runGit(cwd || process.cwd(), ['rev-parse', '--show-toplevel']);
162
+ const root = out ? out.trim() : null;
163
+ return root ? { found: true, gitRoot: root } : { found: false };
164
+ },
165
+ gitCommitShaAsync: async (gitRoot) => {
166
+ const out = await runGit(gitRoot, ['rev-parse', 'HEAD']);
167
+ return out ? out.trim() : null;
168
+ },
169
+ gitStatusFilesAsync: async (gitRoot) => {
170
+ // --untracked-files=all: 未追跡ディレクトリを "?? dir/" に畳まず、配下ファイルを個別に列挙させる。
171
+ // SnapshotManager.backupFile はディレクトリを保存できないため、ディレクトリ単位の畳み込みだと
172
+ // 未追跡ディレクトリ配下のファイルが rollback 対象から漏れる。
173
+ const out = await runGit(gitRoot, ['status', '--porcelain=v1', '-z', '--untracked-files=all']);
174
+ if (!out) return [];
175
+ const entries = out.split('\0').filter(Boolean);
176
+ const results = [];
177
+ for (let i = 0; i < entries.length; i++) {
178
+ const entry = entries[i];
179
+ const status = entry.slice(0, 2);
180
+ const relPath = entry.slice(3);
181
+ // rename/copy: X or Y can be 'R'/'C' (index or worktree side); -z format is "to\0from\0"
182
+ const isRenameOrCopy = status[0] === 'R' || status[0] === 'C' || status[1] === 'R' || status[1] === 'C';
183
+ if (isRenameOrCopy && entries[i + 1] !== undefined) {
184
+ i++; // skip the old path field
185
+ }
186
+ // 削除(D)されたファイルは lstat/hash 対象が存在しないため除外する。
187
+ if (status[0] === 'D' || status[1] === 'D') continue;
188
+ results.push({ path: path.join(gitRoot, relPath), status });
189
+ }
190
+ return results;
191
+ },
192
+ gitHashFilesPrefixedAsync: async (gitRoot, files) => {
193
+ const list = Array.isArray(files) ? files : [];
194
+ const out = [];
195
+ for (const p of list) {
196
+ const hash = await hashFileContent(gitRoot, p);
197
+ if (hash) out.push({ path: p, hash });
198
+ }
199
+ return out;
200
+ },
201
+ gitHashSingleFileAsync: async (gitRoot, filePath) => {
202
+ const hash = await hashFileContent(gitRoot, filePath);
203
+ return hash || '';
204
+ },
205
+ gitUntrackedPathsWithOptionalDirectoryAsync: async (gitRoot, opts) => {
206
+ const args = ['ls-files', '--others', '--exclude-standard'];
207
+ if (opts && opts.directory) args.push('--directory');
208
+ const out = await runGit(gitRoot, args);
209
+ if (!out) return [];
210
+ return out.split('\n').filter(Boolean);
211
+ },
115
212
  };
116
213
  for (const [key, stub] of Object.entries(GIT_ASYNC_STUBS)) {
117
214
  if (typeof result[key] === 'function') result[key] = stub;
@@ -283,15 +380,17 @@ Module._load = function (request, parent, isMain) {
283
380
  }
284
381
  // --- JS networkFetch* implementation (bionic: tokio networkFetch* are no-op'd) ---
285
382
  // B7 が QXe() から直接呼ばれる MCP 専用パスでクラッシュするため JS で代替。
286
- // networkFetchStreamStart → { requestId, response: Promise<{handle,url,status,statusText,headers}> }
383
+ // networkFetchStreamStart(requestId, req) Promise<{handle,url,status,statusText,headers}>
384
+ // (2026-07-12修正: 実際のCLI本体は requestId を第1引数、req を第2引数として渡し、
385
+ // 戻り値を直接thenableとして扱う。旧実装は1引数・{requestId,response}のラップ返却で
386
+ // この規約と不一致だったため s.then is not a function / Failed to parse URL from undefined
387
+ // エラーの原因になっていた。詳細は docs/KNOWN-BUGS.md AGENT-001参照)
287
388
  // networkFetchStreamRead → Promise<{ done, body?: Uint8Array }>
288
389
  // networkFetchStreamClose → void
289
390
  // networkFetchRequestCancel → void
290
391
  const _nfMap = new Map();
291
- let _nfIdSeq = 3e6;
292
392
 
293
- result.networkFetchStreamStart = function(req) {
294
- const requestId = 'nf-' + (++_nfIdSeq);
393
+ result.networkFetchStreamStart = function(requestId, req) {
295
394
  const abortCtrl = new AbortController();
296
395
  const entry = { abort: () => abortCtrl.abort(), reader: null };
297
396
  _nfMap.set(requestId, entry);
@@ -342,7 +441,7 @@ Module._load = function (request, parent, isMain) {
342
441
  return { handle, url: res.url, status: res.status, statusText: res.statusText, headers: respHeaders };
343
442
  })();
344
443
 
345
- return { requestId, response };
444
+ return response;
346
445
  };
347
446
 
348
447
  result.networkFetchStreamRead = function(handle) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash0816/copilot-termux",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "GitHub Copilot CLI for Termux (Android aarch64)",
5
5
  "license": "GPL-3.0-only",
6
6
  "readme": "README.md",