codiedev 0.9.51 → 0.9.53

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.
Files changed (50) hide show
  1. package/README.md +8 -1
  2. package/dist/captureLog.d.ts +1 -1
  3. package/dist/cli.js +7 -22
  4. package/dist/codie.js +1 -146
  5. package/dist/codieLauncher.d.ts +0 -5
  6. package/dist/codieLauncher.js +1 -22
  7. package/dist/codieRuntime.d.ts +1 -11
  8. package/dist/codieRuntime.js +3 -20
  9. package/dist/codieRuntimeInstall.d.ts +11 -12
  10. package/dist/codieRuntimeInstall.js +1 -3
  11. package/dist/commands/doctor.js +0 -8
  12. package/dist/connect.js +4 -53
  13. package/dist/cursorHooks.d.ts +9 -0
  14. package/dist/cursorHooks.js +56 -0
  15. package/dist/hook.js +95 -227
  16. package/dist/limitEvent.d.ts +4 -1
  17. package/dist/limitEvent.js +54 -0
  18. package/dist/limitEventReporter.d.ts +21 -0
  19. package/dist/limitEventReporter.js +91 -0
  20. package/dist/mcp.js +1 -93
  21. package/dist/repoResolver.js +1 -1
  22. package/dist/upgradeNudge.d.ts +0 -1
  23. package/dist/upgradeNudge.js +0 -1
  24. package/dist/utils.d.ts +10 -8
  25. package/dist/utils.js +174 -199
  26. package/package.json +5 -11
  27. package/dist/codieStartup.d.ts +0 -24
  28. package/dist/codieStartup.js +0 -29
  29. package/dist/commands/post.d.ts +0 -2
  30. package/dist/commands/post.js +0 -96
  31. package/dist/commands/security.d.ts +0 -1
  32. package/dist/commands/security.js +0 -156
  33. package/dist/security.d.ts +0 -97
  34. package/dist/security.js +0 -422
  35. package/dist/securityDeepScan.d.ts +0 -41
  36. package/dist/securityDeepScan.js +0 -248
  37. package/dist/securityDoctor.d.ts +0 -32
  38. package/dist/securityDoctor.js +0 -63
  39. package/dist/securityFeature.d.ts +0 -5
  40. package/dist/securityFeature.js +0 -7
  41. package/dist/securityInstall.d.ts +0 -62
  42. package/dist/securityInstall.js +0 -227
  43. package/dist/securityInventory.d.ts +0 -54
  44. package/dist/securityInventory.js +0 -556
  45. package/dist/securityPilot.d.ts +0 -19
  46. package/dist/securityPilot.js +0 -61
  47. package/dist/securityPolicy.d.ts +0 -32
  48. package/dist/securityPolicy.js +0 -179
  49. package/dist/securitySession.d.ts +0 -6
  50. package/dist/securitySession.js +0 -72
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.refreshCodieSecurityPolicy = refreshCodieSecurityPolicy;
4
- const securityFeature_1 = require("./securityFeature");
5
- const securityPolicy_1 = require("./securityPolicy");
6
- /** Refresh the endpoint policy before Codie hands the terminal to OpenCode.
7
- * Enforcement remains available offline because hooks keep using the last
8
- * verified company-scoped policy when this best-effort refresh cannot land. */
9
- async function refreshCodieSecurityPolicy(config, syncPolicy = securityPolicy_1.syncEndpointSecurityPolicy) {
10
- if (!(0, securityFeature_1.isAgentSecurityEnabled)(config))
11
- return { status: "disabled" };
12
- if (!config.backendUrl || !config.token || !config.companyId) {
13
- return { status: "cached", error: "connected account details are incomplete" };
14
- }
15
- try {
16
- const policy = await syncPolicy({
17
- backendUrl: config.backendUrl,
18
- token: config.token,
19
- companyId: config.companyId,
20
- }, "codie-harness");
21
- return { status: "synced", policy };
22
- }
23
- catch (error) {
24
- return {
25
- status: "cached",
26
- error: error instanceof Error ? error.message : String(error),
27
- };
28
- }
29
- }
@@ -1,2 +0,0 @@
1
- import type { CodiedevConfig } from "../utils";
2
- export declare function runPost(args: string[], configOverride?: CodiedevConfig): Promise<void>;
@@ -1,96 +0,0 @@
1
- "use strict";
2
- // `codiedev post --title ... --body ... [--intent share|...] [--filename ...]
3
- // [--mention NAME ...] [--tag X ...]` — publish to the team feed. Intended
4
- // for broad-team reach: announcing a skill, asking who knows about X,
5
- // proposing a change. Use `codiedev send` to address a single teammate.
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.runPost = runPost;
8
- const shared_1 = require("./shared");
9
- const VALID_INTENTS = new Set([
10
- "share",
11
- "request_review",
12
- "request_expertise",
13
- "link_share",
14
- "rfc",
15
- ]);
16
- const VALID_FORMATS = new Set(["article", "quick", "workflow", "review"]);
17
- function parseArgs(args) {
18
- let title;
19
- let body;
20
- let intent;
21
- let filename;
22
- let format;
23
- const mentions = [];
24
- const tags = [];
25
- for (let i = 0; i < args.length; i++) {
26
- const a = args[i];
27
- const next = (k) => a === k && i + 1 < args.length ? args[++i] : a.startsWith(k + "=") ? a.slice(k.length + 1) : undefined;
28
- let v;
29
- if ((v = next("--title")) !== undefined)
30
- title = v;
31
- else if ((v = next("--body")) !== undefined)
32
- body = v;
33
- else if ((v = next("--intent")) !== undefined)
34
- intent = v;
35
- else if ((v = next("--filename")) !== undefined)
36
- filename = v;
37
- else if ((v = next("--format")) !== undefined)
38
- format = v;
39
- else if ((v = next("--mention")) !== undefined)
40
- mentions.push(v);
41
- else if ((v = next("--tag")) !== undefined)
42
- tags.push(v);
43
- }
44
- if (!title || !title.trim()) {
45
- console.error('Usage: codiedev post --title "<title>" --body "<body>" [--intent share|request_review|request_expertise|link_share|rfc] [--filename <key>] [--mention <name>]...');
46
- process.exit(1);
47
- }
48
- if (!body || !body.trim()) {
49
- console.error("--body required");
50
- process.exit(1);
51
- }
52
- if (intent && !VALID_INTENTS.has(intent)) {
53
- console.error(`Invalid --intent. Valid: ${[...VALID_INTENTS].join(", ")}`);
54
- process.exit(1);
55
- }
56
- if (format && !VALID_FORMATS.has(format)) {
57
- console.error(`Invalid --format. Valid: ${[...VALID_FORMATS].join(", ")}`);
58
- process.exit(1);
59
- }
60
- return { title, body, intent, filename, format, mentions, tags };
61
- }
62
- async function runPost(args, configOverride) {
63
- const parsed = parseArgs(args);
64
- const config = configOverride ?? (0, shared_1.requireConfig)();
65
- const start = Date.now();
66
- try {
67
- const res = await (0, shared_1.apiRequest)("POST", "/api/cli/post-to-feed", {
68
- config,
69
- body: {
70
- title: parsed.title,
71
- body: parsed.body,
72
- intent: parsed.intent,
73
- filename: parsed.filename,
74
- format: parsed.format,
75
- mentions: parsed.mentions.length > 0 ? parsed.mentions : undefined,
76
- tags: parsed.tags.length > 0 ? parsed.tags : undefined,
77
- },
78
- });
79
- (0, shared_1.recordAgentEvent)(config, {
80
- tool: "codiedev_post_to_feed",
81
- ok: true,
82
- latencyMs: Date.now() - start,
83
- });
84
- console.log(`Posted to the team feed${res.postId ? ` (id: ${res.postId})` : ""}.`);
85
- }
86
- catch (err) {
87
- (0, shared_1.recordAgentEvent)(config, {
88
- tool: "codiedev_post_to_feed",
89
- ok: false,
90
- latencyMs: Date.now() - start,
91
- error: err.message,
92
- });
93
- console.error(`Post failed: ${err.message}`);
94
- process.exit(1);
95
- }
96
- }
@@ -1 +0,0 @@
1
- export declare function runSecurityCommand(args: string[]): Promise<void>;
@@ -1,156 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runSecurityCommand = runSecurityCommand;
4
- const securityInstall_1 = require("../securityInstall");
5
- const securityPilot_1 = require("../securityPilot");
6
- const securityPolicy_1 = require("../securityPolicy");
7
- const securityInventory_1 = require("../securityInventory");
8
- const securityDeepScan_1 = require("../securityDeepScan");
9
- const utils_1 = require("../utils");
10
- const securityDoctor_1 = require("../securityDoctor");
11
- const securityFeature_1 = require("../securityFeature");
12
- const SECURITY_USAGE = "Usage: codiedev security <doctor|pilot|inventory|scan|sync|rollback> [--json] [--deep] [--connect-mcp] [--supply-chain] [--no-upload] [--yes]";
13
- function printPilot(json) {
14
- const report = (0, securityPilot_1.runSyntheticSecurityPilot)();
15
- if (json) {
16
- console.log(JSON.stringify(report, null, 2));
17
- return report.ok;
18
- }
19
- console.log("\nCodiedev security pilot — synthetic, side-effect-free validation\n");
20
- for (const item of report.cases) {
21
- console.log(`${item.passed ? "✓" : "✗"} ${item.surface}: ${item.name} (${item.actual})`);
22
- }
23
- console.log(`\n${report.ok ? "PASS" : "FAIL"}: ${report.cases.filter((item) => item.passed).length}/${report.cases.length} policy checks matched.`);
24
- console.log("No commands were executed and no real credentials were used.\n");
25
- return report.ok;
26
- }
27
- function printDoctor(json, companyId) {
28
- const result = (0, securityDoctor_1.collectSecurityDoctorReport)(companyId);
29
- if (json) {
30
- console.log(JSON.stringify(result, null, 2));
31
- return result.ok;
32
- }
33
- console.log("\nCodiedev doctor — Agent Security details\n");
34
- for (const check of (0, securityDoctor_1.securityDoctorChecks)(result)) {
35
- const mark = check.status === "pass" ? "✓" : check.status === "warn" ? "!" : "✗";
36
- console.log(`${mark} ${check.name}: ${check.detail}`);
37
- }
38
- console.log(`\n${result.ok ? "PASS" : "FAIL"}: ${result.ok ? "endpoint security is healthy" : "run `codiedev connect`, then repeat this check"}.\n`);
39
- return result.ok;
40
- }
41
- async function runSecurityCommand(args) {
42
- const subcommand = args.find((arg) => !arg.startsWith("-")) ?? "doctor";
43
- const json = args.includes("--json");
44
- if (args.includes("--help") || args.includes("-h") || subcommand === "help") {
45
- console.log(SECURITY_USAGE);
46
- return;
47
- }
48
- const connectedConfig = (0, utils_1.readConfig)();
49
- const requiresEntitlement = !["pilot", "self-test"].includes(subcommand);
50
- if (requiresEntitlement && (!connectedConfig || !(0, securityFeature_1.isAgentSecurityEnabled)(connectedConfig))) {
51
- const detail = connectedConfig
52
- ? `Agent Security is not enabled for ${connectedConfig.companyName}.`
53
- : "Not connected. Run `codiedev connect` first.";
54
- if (json)
55
- console.log(JSON.stringify({ schemaVersion: 1, enabled: false, detail }, null, 2));
56
- else
57
- console.log(`\n${detail}\n`);
58
- return;
59
- }
60
- if (subcommand === "inventory" || subcommand === "scan") {
61
- const workspaceFlag = args.indexOf("--workspace");
62
- const workspace = workspaceFlag >= 0 && args[workspaceFlag + 1]
63
- ? args[workspaceFlag + 1]
64
- : process.cwd();
65
- const inventory = (0, securityInventory_1.buildSecurityInventory)({ workspace });
66
- const deep = subcommand === "scan" && args.includes("--deep")
67
- ? (0, securityDeepScan_1.runDeepSecurityScan)(inventory, {
68
- workspace,
69
- connectMcp: args.includes("--connect-mcp"),
70
- supplyChain: args.includes("--supply-chain"),
71
- })
72
- : undefined;
73
- const uploadableInventory = deep ? (0, securityDeepScan_1.mergeDeepScanFindings)(inventory, deep) : inventory;
74
- let upload;
75
- const config = (0, utils_1.readConfig)();
76
- if (config && !args.includes("--no-upload")) {
77
- try {
78
- upload = await (0, securityInventory_1.uploadSecurityInventory)(uploadableInventory, config);
79
- }
80
- catch (error) {
81
- if (!json)
82
- console.warn(`Inventory upload failed; local scan is still valid: ${error.message}`);
83
- }
84
- }
85
- const output = { inventory: uploadableInventory, scanners: (0, securityInventory_1.scannerAvailability)(), ...(deep ? { deep } : {}), ...(upload ? { upload } : {}) };
86
- if (json)
87
- console.log(JSON.stringify(output, null, 2));
88
- else {
89
- const risky = inventory.components.filter((component) => component.findings.length > 0).length;
90
- console.log(`\nCodiedev security inventory — ${inventory.components.length} components, ${risky} with local findings, ${inventory.drift.length} changed\n`);
91
- const counts = new Map();
92
- for (const component of inventory.components)
93
- counts.set(component.kind, (counts.get(component.kind) ?? 0) + 1);
94
- for (const [kind, count] of [...counts].sort())
95
- console.log(` ${kind}: ${count}`);
96
- if (deep)
97
- for (const run of deep.runs)
98
- console.log(` ${run.scanner}: ${run.status} — ${run.detail}`);
99
- if (upload)
100
- console.log(`\nUploaded ${upload.accepted} component records to the security workspace.`);
101
- console.log("\nUse --json for machine-readable hashes and findings. Use scan --deep for installed OSS scanners; --connect-mcp and --supply-chain are explicit because they start or download third-party code.\n");
102
- }
103
- return;
104
- }
105
- if (subcommand === "sync") {
106
- const config = (0, utils_1.readConfig)();
107
- if (!config) {
108
- console.error("Not connected. Run `codiedev connect` first.");
109
- process.exitCode = 1;
110
- return;
111
- }
112
- try {
113
- const policy = await (0, securityPolicy_1.syncEndpointSecurityPolicy)(config);
114
- if (json)
115
- console.log(JSON.stringify({ ok: true, policy }, null, 2));
116
- else {
117
- const verification = (0, securityPolicy_1.verifyEndpointSecurityPolicySignature)(policy);
118
- console.log(`Security policy v${policy.policyVersion} synced (${policy.enforcementMode} mode; ${verification.detail}).`);
119
- }
120
- }
121
- catch (error) {
122
- console.error(`Security policy sync failed: ${error.message}`);
123
- process.exitCode = 1;
124
- }
125
- return;
126
- }
127
- if (subcommand === "rollback") {
128
- if (!args.includes("--yes")) {
129
- console.error("Rollback overwrites the installed agent hook configurations. Re-run with `codiedev security rollback --yes` after confirming the snapshot shown by `codiedev doctor`.");
130
- process.exitCode = 1;
131
- return;
132
- }
133
- try {
134
- const result = (0, securityInstall_1.restoreSecurityInstallSnapshot)((0, securityInstall_1.readSecurityInstallManifest)());
135
- if (json)
136
- console.log(JSON.stringify({ schemaVersion: 1, ok: true, ...result }, null, 2));
137
- else
138
- console.log(`Restored ${result.restored} hook configuration(s) from snapshot ${result.snapshotId}.`);
139
- }
140
- catch (error) {
141
- console.error(`Rollback failed: ${error.message}`);
142
- process.exitCode = 1;
143
- }
144
- return;
145
- }
146
- const ok = subcommand === "pilot" || subcommand === "self-test"
147
- ? printPilot(json)
148
- : subcommand === "doctor" || subcommand === "status"
149
- ? printDoctor(json, connectedConfig.companyId)
150
- : false;
151
- if (!["pilot", "self-test", "doctor", "status"].includes(subcommand)) {
152
- console.error(SECURITY_USAGE);
153
- }
154
- if (!ok)
155
- process.exitCode = 1;
156
- }
@@ -1,97 +0,0 @@
1
- export type SecurityHookPhase = "pre" | "post" | "failure";
2
- export type AgentSurface = "claude-code" | "codex" | "codie-harness";
3
- export interface RawSecurityHookInput {
4
- session_id?: string;
5
- sessionId?: string;
6
- cwd?: string;
7
- hook_event_name?: string;
8
- hookEventName?: string;
9
- tool_name?: string;
10
- toolName?: string;
11
- tool_input?: unknown;
12
- toolInput?: unknown;
13
- tool_response?: unknown;
14
- toolResponse?: unknown;
15
- tool_use_id?: string;
16
- toolUseId?: string;
17
- duration_ms?: number;
18
- durationMs?: number;
19
- error?: unknown;
20
- prompt?: string;
21
- }
22
- export interface SecurityWorkflowEvent {
23
- schemaVersion: 1;
24
- source: AgentSurface;
25
- phase: SecurityHookPhase;
26
- sessionId: string;
27
- toolName: string;
28
- toolUseId?: string;
29
- cwd?: string;
30
- observedAt: number;
31
- toolDurationMs?: number;
32
- payload: unknown;
33
- redactionCount: number;
34
- localDecision?: LocalSecurityAction;
35
- localCategory?: LocalSecurityDecision["category"];
36
- endpointId?: string;
37
- endpointName?: string;
38
- cliVersion?: string;
39
- }
40
- export type LocalSecurityAction = "allow" | "alert" | "block";
41
- export type SecurityCategory = "secret_in_prompt" | "secret_exfiltration" | "destructive_outside_workspace" | "sensitive_file_read" | "sensitive_file_write" | "protected_agent_config_write" | "unapproved_network_egress" | "untrusted_mcp_tool" | "unapproved_command" | "obfuscated_shell_command" | "package_install" | "sensitive_read_then_egress";
42
- export interface EndpointSecurityPolicy {
43
- schemaVersion: 1;
44
- policyVersion: number;
45
- enforcementMode: "alert" | "block";
46
- rules: Partial<Record<SecurityCategory, LocalSecurityAction>>;
47
- constraints?: {
48
- allowedMcpServers?: string[];
49
- allowedHosts?: string[];
50
- allowedCommands?: string[];
51
- };
52
- exceptions: Array<{
53
- scope: "company" | "user" | "source" | "repository" | "tool" | "category";
54
- scopeValue: string;
55
- }>;
56
- fetchedAt: number;
57
- signature?: {
58
- algorithm: "Ed25519";
59
- keyId: string;
60
- signedAt: number;
61
- value: string;
62
- };
63
- }
64
- export interface LocalSecurityDecision {
65
- action: LocalSecurityAction;
66
- category?: SecurityCategory;
67
- reason?: string;
68
- }
69
- export declare function withEndpointIdentity(event: SecurityWorkflowEvent, identity: {
70
- endpointId?: string;
71
- endpointName?: string;
72
- cliVersion?: string;
73
- }): SecurityWorkflowEvent;
74
- /**
75
- * Runs before a user prompt reaches the model. This is intentionally narrow:
76
- * block credential material, but allow safe references such as
77
- * `$OPENAI_API_KEY` so developers can ask agents to use environment variables
78
- * without pasting their values.
79
- */
80
- export declare function evaluatePromptSecurity(prompt: string | undefined, policy?: EndpointSecurityPolicy, source?: AgentSurface): LocalSecurityDecision;
81
- /** Runs synchronously before a tool executes. No network or model is involved. */
82
- export declare function evaluateToolSecurity(input: RawSecurityHookInput, phase: SecurityHookPhase, policy?: EndpointSecurityPolicy, source?: AgentSurface, sessionContext?: {
83
- sensitiveReadAt?: number;
84
- now?: number;
85
- }): LocalSecurityDecision;
86
- export declare function securityInputHasSensitivePath(input: RawSecurityHookInput): boolean;
87
- export declare function buildSecurityWorkflowEvent(input: RawSecurityHookInput, phase: SecurityHookPhase, source: AgentSurface, now?: () => number): SecurityWorkflowEvent | null;
88
- /**
89
- * Captures the intent side of the causal chain without weakening the local
90
- * privacy boundary. A prompt that the deterministic policy blocks never
91
- * becomes an uploadable event; allowed prompts are redacted and bounded using
92
- * the same sanitizer as tool payloads.
93
- */
94
- export declare function buildSecurityPromptEvent(input: Pick<RawSecurityHookInput, "session_id" | "sessionId" | "cwd" | "prompt">, source: AgentSurface, now?: () => number, policy?: EndpointSecurityPolicy): SecurityWorkflowEvent | null;
95
- /** Audit-safe evidence for a blocked prompt. The secret-bearing prompt is
96
- * intentionally omitted; administrators still see that prevention occurred. */
97
- export declare function buildBlockedSecurityPromptEvent(input: Pick<RawSecurityHookInput, "session_id" | "sessionId" | "cwd">, source: AgentSurface, category: NonNullable<LocalSecurityDecision["category"]>, now?: () => number): SecurityWorkflowEvent | null;