Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .opencode/work-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Work Log

## Active Sessions
- [ ] ses_worker_M3_T3_1 (Worker): `packages/core/src/linkedinGroups.ts` - MODIFY pending
17 changes: 17 additions & 0 deletions fix-todo.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require('fs');
const file = '/Users/user/.opencode/todo.md';
let todo = fs.readFileSync(file, 'utf8');

todo = todo.replace(/- \[ \] S2\.1\.1:/, '- [x] S2.1.1:');
todo = todo.replace(/- \[ \] S2\.1\.2:/, '- [x] S2.1.2:');
todo = todo.replace(/status: in_progress/, 'status: completed');

todo = todo.replace(/- \[ \] S3\.1\.1:/, '- [x] S3.1.1:');
todo = todo.replace(/- \[ \] S3\.1\.2:/, '- [x] S3.1.2:');
todo = todo.replace(/- \[ \] S3\.2\.1:/, '- [x] S3.2.1:');

todo = todo.replace(/- \[ \] S4\.1\.1:/, '- [x] S4.1.1:');
todo = todo.replace(/- \[ \] S4\.1\.2:/, '- [x] S4.1.2:');
todo = todo.replace(/- \[ \] S4\.2\.1:/, '- [x] S4.2.1:');

fs.writeFileSync(file, todo);
82 changes: 82 additions & 0 deletions mcp-proper-patch.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const fs = require('fs');

const indexFile = 'packages/mcp/src/index.ts';
let indexCode = fs.readFileSync(indexFile, 'utf8');

indexCode = indexCode.replace(
'export const LINKEDIN_EVENTS_SEARCH_TOOL = "linkedin.events.search";',
'export const LINKEDIN_GROUPS_CREATE_TOOL = "linkedin.groups.create";\nexport const LINKEDIN_EVENTS_CREATE_TOOL = "linkedin.events.create";\nexport const LINKEDIN_EVENTS_SEARCH_TOOL = "linkedin.events.search";'
);
fs.writeFileSync(indexFile, indexCode);

const mcpFile = 'packages/mcp/src/bin/linkedin-mcp.ts';
let mcpCode = fs.readFileSync(mcpFile, 'utf8');

// Add imports
mcpCode = mcpCode.replace(
'LINKEDIN_EVENTS_SEARCH_TOOL,',
'LINKEDIN_GROUPS_CREATE_TOOL,\n LINKEDIN_EVENTS_CREATE_TOOL,\n LINKEDIN_EVENTS_SEARCH_TOOL,'
);

// Add to tool definitions array
const mcpTools = ` {
name: LINKEDIN_GROUPS_CREATE_TOOL,
description: "Create a new LinkedIn group",
inputSchema: {
type: "object",
properties: {
profileName: { type: "string" },
name: { type: "string" },
description: { type: "string" },
},
required: ["name", "description"],
},
},
{
name: LINKEDIN_EVENTS_CREATE_TOOL,
description: "Create a new LinkedIn event",
inputSchema: {
type: "object",
properties: {
profileName: { type: "string" },
name: { type: "string" },
description: { type: "string" },
},
required: ["name", "description"],
},
},`;

mcpCode = mcpCode.replace(
' { name: LINKEDIN_EVENTS_SEARCH_TOOL,',
mcpTools + '\n { name: LINKEDIN_EVENTS_SEARCH_TOOL,'
);

// Handlers
const mcpHandlers = ` case LINKEDIN_GROUPS_CREATE_TOOL: {
const result = await runtime.groups.createGroup({
profileName: String(request.params.arguments?.profileName || "default"),
name: String(request.params.arguments?.name),
description: String(request.params.arguments?.description),
});
return {
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
};
}

case LINKEDIN_EVENTS_CREATE_TOOL: {
const result = await runtime.events.createEvent({
profileName: String(request.params.arguments?.profileName || "default"),
name: String(request.params.arguments?.name),
description: String(request.params.arguments?.description),
});
return {
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
};
}`;

mcpCode = mcpCode.replace(
' case LINKEDIN_EVENTS_SEARCH_TOOL: {',
mcpHandlers + '\n case LINKEDIN_EVENTS_SEARCH_TOOL: {'
);

fs.writeFileSync(mcpFile, mcpCode);
102 changes: 102 additions & 0 deletions packages/cli/src/bin/linkedin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,45 @@ async function captureFixtureResponse(
};
}


async function runCreateGroup(
input: {
profileName: string;
name: string;
description: string;
},
cdpUrl?: string,
): Promise<void> {
const runtime = await createRuntime(cdpUrl);
const result = await runtime.groups.createGroup(input);
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
}

async function runCreateEvent(
input: {
profileName: string;
name: string;
description: string;
},
cdpUrl?: string,
): Promise<void> {
const runtime = await createRuntime(cdpUrl);
const result = await runtime.events.createEvent(input);
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
}

async function runAnalyticsPostMetrics(
input: {
profileName: string;
postUrl: string;
},
cdpUrl?: string,
): Promise<void> {
const runtime = await createRuntime(cdpUrl);
const metrics = await runtime.analytics.getPostMetrics(input);
process.stdout.write(JSON.stringify(metrics, null, 2) + "\n");
}

async function runFixturesCheck(input: {
manifestPath?: string;
maxAgeDays?: number;
Expand Down Expand Up @@ -11321,6 +11360,29 @@ export function createCliProgram(): Command {
)
.action(runFixtureCheckCommand);


const analyticsCommand = program
.command("analytics")
.description("View analytics data");

analyticsCommand
.command("post-metrics")
.description("View metrics for a specific post")
.argument("<postUrl>", "URL of the post")
.option("-p, --profile <profile>", "Profile name", "default")
.action(
async (postUrl: string, options: { profile: string }) => {
await runAnalyticsPostMetrics(
{
profileName: options.profile,
postUrl,
},
readCdpUrl(),
);
},
);


const fixturesCommand = program
.command("fixtures")
.description("Record and validate LinkedIn replay fixture sets");
Expand Down Expand Up @@ -12103,6 +12165,26 @@ export function createCliProgram(): Command {
"Search, view, join, leave, and post in LinkedIn groups",
);


groupsCommand
.command("create")
.description("Create a new LinkedIn group")
.argument("<name>", "Name of the group")
.argument("<description>", "Description of the group")
.option("-p, --profile <profile>", "Profile name", "default")
.action(
async (name: string, description: string, options: { profile: string }) => {
await runCreateGroup(
{
profileName: options.profile,
name,
description,
},
readCdpUrl(),
);
},
);

groupsCommand
.command("search")
.description("Search LinkedIn groups by keyword")
Expand Down Expand Up @@ -12219,6 +12301,26 @@ export function createCliProgram(): Command {
"Search, view, and RSVP to LinkedIn events",
);


eventsCommand
.command("create")
.description("Create a new LinkedIn event")
.argument("<name>", "Name of the event")
.argument("<description>", "Description of the event")
.option("-p, --profile <profile>", "Profile name", "default")
.action(
async (name: string, description: string, options: { profile: string }) => {
await runCreateEvent(
{
profileName: options.profile,
name,
description,
},
readCdpUrl(),
);
},
);

eventsCommand
.command("search")
.description("Search LinkedIn events by keyword")
Expand Down
Loading
Loading