codiedev 0.9.60 → 0.9.62
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/captureSignals.d.ts +4 -0
- package/dist/captureSignals.js +18 -0
- package/dist/cli.js +3 -1
- package/dist/commands/doctor.js +11 -0
- package/dist/connect.js +9 -1
- package/dist/copilotHooks.d.ts +85 -0
- package/dist/copilotHooks.js +458 -0
- package/dist/copilotInstallation.d.ts +10 -0
- package/dist/copilotInstallation.js +65 -0
- package/dist/cursorHooks.d.ts +5 -1
- package/dist/cursorHooks.js +50 -7
- package/dist/cursorLifecycle.d.ts +2 -0
- package/dist/cursorLifecycle.js +115 -0
- package/dist/hook.js +133 -36
- package/dist/launchContext.d.ts +20 -6
- package/dist/launchContext.js +65 -10
- package/dist/limitEvent.d.ts +3 -0
- package/dist/limitEvent.js +42 -0
- package/dist/limitEventReporter.d.ts +1 -1
- package/dist/limitEventReporter.js +1 -1
- package/dist/nativeSteering.d.ts +5 -0
- package/dist/nativeSteering.js +27 -0
- package/dist/teamSkillContext.d.ts +9 -0
- package/dist/teamSkillContext.js +11 -0
- package/dist/transcriptModels.d.ts +2 -0
- package/dist/transcriptModels.js +8 -2
- package/dist/utils.d.ts +19 -3
- package/dist/utils.js +162 -43
- package/package.json +7 -4
package/dist/captureSignals.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export type CaptureSignals = {
|
|
|
28
28
|
count: number;
|
|
29
29
|
truncated: boolean;
|
|
30
30
|
};
|
|
31
|
+
/** GitHub Copilot subscription usage: premium requests and nano-AIU, from
|
|
32
|
+
* the session's latest usage checkpoint or its shutdown. Not dollars. */
|
|
33
|
+
premiumRequests?: number;
|
|
34
|
+
nanoAiu?: number;
|
|
31
35
|
truncated: boolean;
|
|
32
36
|
};
|
|
33
37
|
/** Compact diagnostic inputs only: never persist prompts, commands or tool output. */
|
package/dist/captureSignals.js
CHANGED
|
@@ -22,6 +22,8 @@ function parseCaptureSignals(content, source) {
|
|
|
22
22
|
const invocations = new Set(), pulls = new Set(), entrypoints = new Set();
|
|
23
23
|
const tools = new Map(), calls = new Set();
|
|
24
24
|
let parsedRecords = 0, truncated = false;
|
|
25
|
+
let premiumRequests, nanoAiu;
|
|
26
|
+
let cursorSubagents;
|
|
25
27
|
const addSkill = (set, value) => {
|
|
26
28
|
const key = skillKey(value);
|
|
27
29
|
if (!key || key.length > 200 || !/^[a-z0-9][a-z0-9_:/.-]*$/i.test(key))
|
|
@@ -88,6 +90,19 @@ function parseCaptureSignals(content, source) {
|
|
|
88
90
|
? `codex:${Object.keys(src)[0] ?? "other"}`
|
|
89
91
|
: undefined);
|
|
90
92
|
}
|
|
93
|
+
if (e.type === "cursor.subagent_summary" && Number.isSafeInteger(e.count) && e.count > 0) {
|
|
94
|
+
cursorSubagents = { count: e.count, truncated: e.truncated === true };
|
|
95
|
+
}
|
|
96
|
+
// GitHub Copilot (normalized): one skill.invoked event per skill run,
|
|
97
|
+
// whether the user or the agent invoked it.
|
|
98
|
+
if (e.type === "copilot.skill_invoked")
|
|
99
|
+
addSkill(invocations, e.skill);
|
|
100
|
+
if (e.type === "copilot.usage_summary") {
|
|
101
|
+
if (typeof e.premiumRequests === "number" && e.premiumRequests >= 0)
|
|
102
|
+
premiumRequests = e.premiumRequests;
|
|
103
|
+
if (typeof e.nanoAiu === "number" && e.nanoAiu >= 0)
|
|
104
|
+
nanoAiu = e.nanoAiu;
|
|
105
|
+
}
|
|
91
106
|
const time = typeof e.timestamp === "string"
|
|
92
107
|
? Date.parse(e.timestamp)
|
|
93
108
|
: e.info?.time?.created;
|
|
@@ -139,7 +154,10 @@ function parseCaptureSignals(content, source) {
|
|
|
139
154
|
toolCalls: [...tools]
|
|
140
155
|
.map(([name, calls]) => ({ name, calls }))
|
|
141
156
|
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
157
|
+
...(cursorSubagents ? { subagents: cursorSubagents } : {}),
|
|
142
158
|
...(entrypoints.size ? { entrypoints: [...entrypoints].sort() } : {}),
|
|
159
|
+
...(premiumRequests !== undefined ? { premiumRequests } : {}),
|
|
160
|
+
...(nanoAiu !== undefined ? { nanoAiu } : {}),
|
|
143
161
|
truncated,
|
|
144
162
|
};
|
|
145
163
|
}
|
package/dist/cli.js
CHANGED
|
@@ -42,7 +42,8 @@ Codiedev CLI
|
|
|
42
42
|
someone left off across sessions and providers.
|
|
43
43
|
|
|
44
44
|
Connect:
|
|
45
|
-
codiedev connect Link Claude Code / Codex / Cursor
|
|
45
|
+
codiedev connect Link Claude Code / Codex / Cursor /
|
|
46
|
+
GitHub Copilot to your org
|
|
46
47
|
codiedev doctor Verify your setup after connecting
|
|
47
48
|
|
|
48
49
|
Harness:
|
|
@@ -163,6 +164,7 @@ codiedev connect — link your agent CLI to Codiedev
|
|
|
163
164
|
- ~/.codex/AGENTS.md instructions (same, for Codex)
|
|
164
165
|
- ~/.cursor/hooks.json hooks (session, prompt, security, capture)
|
|
165
166
|
- ~/.cursor/rules/codiedev.mdc (teaches Cursor the commands)
|
|
167
|
+
- ~/.copilot/hooks/codiedev.json (GitHub Copilot: VS Code + CLI capture)
|
|
166
168
|
|
|
167
169
|
Re-run anytime to swap accounts or refresh the instruction block.
|
|
168
170
|
|
package/dist/commands/doctor.js
CHANGED
|
@@ -45,6 +45,7 @@ const version_1 = require("../version");
|
|
|
45
45
|
const upgradeNudge_1 = require("../upgradeNudge");
|
|
46
46
|
const captureReadiness_1 = require("../captureReadiness");
|
|
47
47
|
const captureLog_1 = require("../captureLog");
|
|
48
|
+
const copilotInstallation_1 = require("../copilotInstallation");
|
|
48
49
|
const CLAUDE_SETTINGS_PATH = path.join(os.homedir(), ".claude", "settings.json");
|
|
49
50
|
const CLAUDE_INSTRUCTIONS_PATH = path.join(os.homedir(), ".claude", "CLAUDE.md");
|
|
50
51
|
const CODEX_HOOKS_PATH = path.join(os.homedir(), ".codex", "hooks.json");
|
|
@@ -482,6 +483,16 @@ async function runDoctor(_args) {
|
|
|
482
483
|
detail: "not installed on this machine",
|
|
483
484
|
});
|
|
484
485
|
}
|
|
486
|
+
if ((0, utils_1.copilotInstalled)()) {
|
|
487
|
+
const hooks = (0, copilotInstallation_1.inspectCopilotHooks)();
|
|
488
|
+
checks.push({ name: "GitHub Copilot capture hooks", status: hooks.status === "pass" ? "pass" : "fail", detail: hooks.detail });
|
|
489
|
+
checks.push({ name: "GitHub Copilot CLI instructions",
|
|
490
|
+
status: hasCodiedevInstructions((0, utils_1.copilotInstructionsPath)()) ? "pass" : "fail",
|
|
491
|
+
detail: hasCodiedevInstructions((0, utils_1.copilotInstructionsPath)()) ? (0, utils_1.copilotInstructionsPath)() : "missing — re-run `codiedev connect`" });
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
checks.push({ name: "GitHub Copilot", status: "warn", detail: "not installed on this machine" });
|
|
495
|
+
}
|
|
485
496
|
// 8. gh / glab CLIs (optional — only needed for reverse-ticket from a
|
|
486
497
|
// specific PR/MR URL; branch mode works without either).
|
|
487
498
|
checks.push({
|
package/dist/connect.js
CHANGED
|
@@ -271,10 +271,12 @@ async function runConnect(args = []) {
|
|
|
271
271
|
const hasCodex = (0, utils_1.codexInstalled)();
|
|
272
272
|
const hasCursor = (0, utils_1.cursorInstalled)();
|
|
273
273
|
const hasOpenCode = (0, utils_1.openCodeInstalled)();
|
|
274
|
+
const hasCopilot = (0, utils_1.copilotInstalled)();
|
|
274
275
|
(0, shared_1.recordInstallEvent)(config, { step: "detect", target: "claude-code", ok: hasClaude });
|
|
275
276
|
(0, shared_1.recordInstallEvent)(config, { step: "detect", target: "codex", ok: hasCodex });
|
|
276
277
|
(0, shared_1.recordInstallEvent)(config, { step: "detect", target: "cursor", ok: hasCursor });
|
|
277
278
|
(0, shared_1.recordInstallEvent)(config, { step: "detect", target: "opencode", ok: hasOpenCode });
|
|
279
|
+
(0, shared_1.recordInstallEvent)(config, { step: "detect", target: "copilot", ok: hasCopilot });
|
|
278
280
|
const installed = [];
|
|
279
281
|
// Machine-readable target keys reported back to the backend via
|
|
280
282
|
// /api/cli/markInstalled so the portal's "Connected" state reflects
|
|
@@ -313,6 +315,12 @@ async function runConnect(args = []) {
|
|
|
313
315
|
runInstall("cursor-hook", utils_1.installCursorHook, "Cursor sessionStart + stop backup + sessionEnd capture hooks (~/.cursor/hooks.json)", "cursor-hook");
|
|
314
316
|
runInstall("cursor-instructions", utils_1.installCursorInstructions, "Cursor agent instructions (~/.cursor/rules/codiedev.mdc)", "cursor-instructions");
|
|
315
317
|
}
|
|
318
|
+
// One user-level hook file covers both VS Code Copilot Chat and the Copilot
|
|
319
|
+
// CLI (they share the runtime and its hooks).
|
|
320
|
+
if (hasCopilot) {
|
|
321
|
+
runInstall("copilot-hook", () => (0, utils_1.installCopilotHook)(), `GitHub Copilot (VS Code + CLI) sessionStart + agentStop backup + sessionEnd capture hooks (${(0, utils_1.copilotHooksPath)()})`, "copilot-hook");
|
|
322
|
+
runInstall("copilot-instructions", utils_1.installCopilotInstructions, "GitHub Copilot CLI team artifact instructions", "copilot-instructions");
|
|
323
|
+
}
|
|
316
324
|
// Always stage the adapter. It is dormant until OpenCode starts, which lets
|
|
317
325
|
// a user connect Claude Code today and install the Codie harness tomorrow
|
|
318
326
|
// without needing a second setup ritual.
|
|
@@ -339,7 +347,7 @@ async function runConnect(args = []) {
|
|
|
339
347
|
});
|
|
340
348
|
}
|
|
341
349
|
}
|
|
342
|
-
if (!hasClaude && !hasCodex && !hasCursor && !hasOpenCode) {
|
|
350
|
+
if (!hasClaude && !hasCodex && !hasCursor && !hasOpenCode && !hasCopilot) {
|
|
343
351
|
console.warn("\nNo existing AI client detected; the Codie/OpenCode adapter is ready for a later install.");
|
|
344
352
|
console.warn("If you just installed Claude Code, launch it once (so ~/.claude is created),");
|
|
345
353
|
console.warn("then re-run `npx codiedev connect` to wire up the capture hook.");
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot: VS Code Copilot Chat's agent and the Copilot CLI run on the
|
|
3
|
+
* same runtime and write the same session record,
|
|
4
|
+
* `$COPILOT_HOME/session-state/<sessionId>/events.jsonl` (plus
|
|
5
|
+
* `workspace.yaml`), and both read user hooks from `$COPILOT_HOME/hooks/*.json`.
|
|
6
|
+
* Everything Copilot-specific is translated here, at the process boundary, so
|
|
7
|
+
* the shared capture pipeline only ever sees the Claude-shaped transcript it
|
|
8
|
+
* already parses.
|
|
9
|
+
*/
|
|
10
|
+
/** `$COPILOT_HOME`, else `~/.copilot` (the runtime honours the same variable). */
|
|
11
|
+
export declare function copilotHome(env?: NodeJS.ProcessEnv, home?: string): string;
|
|
12
|
+
export declare function copilotSessionDir(sessionId: string, home?: string): string | undefined;
|
|
13
|
+
/** sessionEnd carries no transcript path; the session id names the file. */
|
|
14
|
+
export declare function copilotTranscriptPath(sessionId: string | undefined, home?: string): string | undefined;
|
|
15
|
+
export type CopilotWorkspace = {
|
|
16
|
+
id?: string;
|
|
17
|
+
cwd?: string;
|
|
18
|
+
gitRoot?: string;
|
|
19
|
+
branch?: string;
|
|
20
|
+
/** "vscode-agent-host" (VS Code Copilot Chat) or "github/cli" (Copilot CLI). */
|
|
21
|
+
clientName?: string;
|
|
22
|
+
};
|
|
23
|
+
/** workspace.yaml is flat `key: value` lines; no YAML dependency needed. */
|
|
24
|
+
export declare function parseCopilotWorkspace(yaml: string): CopilotWorkspace;
|
|
25
|
+
/** The workspace.yaml beside a transcript (or for a session id); {} if absent. */
|
|
26
|
+
export declare function readCopilotWorkspace(transcriptPathOrDir: string | undefined): CopilotWorkspace;
|
|
27
|
+
export declare const COPILOT_VSCODE_CLIENT = "vscode-agent-host";
|
|
28
|
+
/**
|
|
29
|
+
* How the session was launched. VS Code names itself in workspace.yaml; the
|
|
30
|
+
* CLI doesn't record whether it ran headless, so that comes from the process
|
|
31
|
+
* that launched the hook (`detected`, see launchContext). Unknown stays
|
|
32
|
+
* unknown rather than guessing "human".
|
|
33
|
+
*/
|
|
34
|
+
export declare function copilotLaunch(clientName: string | undefined, detected: string | undefined): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Copilot's hook payloads are camelCase (`sessionId`, `transcriptPath`,
|
|
37
|
+
* `toolName`/`toolArgs`/`toolResult`); preToolUse in the CLI batches calls as
|
|
38
|
+
* `toolCalls: [{id, name, args}]`. Translate to the shared snake_case shape.
|
|
39
|
+
* The FIRST tool call fills tool_name/tool_input; `copilotToolCalls` keeps all
|
|
40
|
+
* of them so security can check each.
|
|
41
|
+
*/
|
|
42
|
+
export declare function normalizeCopilotHookInput<T extends Record<string, unknown>>(input: T, home?: string): T & Record<string, unknown>;
|
|
43
|
+
export type CopilotToolCall = {
|
|
44
|
+
id?: string;
|
|
45
|
+
name: string;
|
|
46
|
+
input: unknown;
|
|
47
|
+
};
|
|
48
|
+
/** Copilot's preToolUse deny output. */
|
|
49
|
+
export declare function copilotPreToolBlockResponse(reason: string): {
|
|
50
|
+
permissionDecision: "deny";
|
|
51
|
+
permissionDecisionReason: string;
|
|
52
|
+
};
|
|
53
|
+
/** Only a byte-empty record is safe to discard (same rule as Cursor). */
|
|
54
|
+
export declare function isCopilotTranscriptEmpty(content: string): boolean;
|
|
55
|
+
/** session.shutdown carries the per-model token totals; written after sessionEnd. */
|
|
56
|
+
export declare function hasCopilotShutdown(content: string): boolean;
|
|
57
|
+
export type NormalizedCopilotTranscript = {
|
|
58
|
+
/** Claude-shaped JSONL for the shared parsers and the upload. */
|
|
59
|
+
content: string;
|
|
60
|
+
/** Fleet-mode sub-agents run inside this file (subagent.started). */
|
|
61
|
+
subagents: {
|
|
62
|
+
count: number;
|
|
63
|
+
truncated: boolean;
|
|
64
|
+
};
|
|
65
|
+
/** True once session.shutdown (token totals) has been written. */
|
|
66
|
+
final: boolean;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* events.jsonl → Claude-shaped JSONL:
|
|
70
|
+
* session.start → system record (cwd, branch, entrypoint for VS Code)
|
|
71
|
+
* user.message → user text
|
|
72
|
+
* assistant.message → assistant text + tool_use blocks (model on every call)
|
|
73
|
+
* tool.execution_complete→ user tool_result (git output feeds branch/sha joins)
|
|
74
|
+
* skill.invoked → copilot.skill_invoked (one skill run)
|
|
75
|
+
* session.shutdown → copilot.usage per model (tokens, sub-agents
|
|
76
|
+
* included; requests counted from the assistant
|
|
77
|
+
* calls, so 0 here) + copilot.usage_summary
|
|
78
|
+
* session.usage_checkpoint → copilot.usage_summary (premium requests and
|
|
79
|
+
* nano-AIU so far; superseded by shutdown)
|
|
80
|
+
* subagent.started → counted as a fleet sub-agent
|
|
81
|
+
* Hooks, permissions, system prompts and checkpoints are dropped.
|
|
82
|
+
*/
|
|
83
|
+
export declare function normalizeCopilotTranscript(raw: string, opts?: {
|
|
84
|
+
clientName?: string;
|
|
85
|
+
}): NormalizedCopilotTranscript;
|