linkedin-apply-assistant 0.1.1
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/.github/ISSUE_TEMPLATE/bug_report.yml +72 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/config_help.yml +49 -0
- package/.github/ISSUE_TEMPLATE/docs.yml +40 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +45 -0
- package/.github/ISSUE_TEMPLATE/safety_compliance.yml +48 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +43 -0
- package/CHANGELOG.md +47 -0
- package/CODE_OF_CONDUCT.md +47 -0
- package/CONTRIBUTING.md +64 -0
- package/GOVERNANCE.md +41 -0
- package/LEGAL.md +38 -0
- package/LICENSE +22 -0
- package/MIGRATION.md +50 -0
- package/README.md +167 -0
- package/RELEASE_CHECKLIST.md +454 -0
- package/SAFETY.md +33 -0
- package/SECURITY.md +37 -0
- package/SUPPORT.md +44 -0
- package/THIRD_PARTY_NOTICES.md +67 -0
- package/bin/linkedin-apply-assistant.mjs +95 -0
- package/configs/config.example.yml +24 -0
- package/configs/qa_bank.example.yml +35 -0
- package/docs/apply.md +40 -0
- package/docs/assist.md +35 -0
- package/docs/browser-session.md +45 -0
- package/docs/ci-and-release-policy.md +105 -0
- package/docs/commands.md +176 -0
- package/docs/install-and-configuration.md +265 -0
- package/docs/registry-publication-strategy.md +169 -0
- package/docs/reports.md +35 -0
- package/docs/search.md +39 -0
- package/docs/troubleshooting.md +57 -0
- package/examples/dry_run_input.example.json +25 -0
- package/examples/reports/apply-audit.example.json +31 -0
- package/examples/reports/search-report.example.json +40 -0
- package/install.ps1 +178 -0
- package/package.json +59 -0
- package/pyproject.toml +51 -0
- package/src/linkedin_apply_assistant/__init__.py +8 -0
- package/src/linkedin_apply_assistant/apply_reports.py +229 -0
- package/src/linkedin_apply_assistant/ats_handlers.py +217 -0
- package/src/linkedin_apply_assistant/browser_sessions.py +155 -0
- package/src/linkedin_apply_assistant/cli.py +570 -0
- package/src/linkedin_apply_assistant/config.py +109 -0
- package/src/linkedin_apply_assistant/contracts.py +255 -0
- package/src/linkedin_apply_assistant/form_engine.py +180 -0
- package/src/linkedin_apply_assistant/linkedin_layer.py +436 -0
- package/src/linkedin_apply_assistant/page_actions.py +110 -0
- package/src/linkedin_apply_assistant/page_selectors.py +88 -0
- package/src/linkedin_apply_assistant/paths.py +135 -0
- package/src/linkedin_apply_assistant/qa_bank.py +352 -0
- package/src/linkedin_apply_assistant/redaction.py +119 -0
- package/src/linkedin_apply_assistant/safety.py +230 -0
- package/src/linkedin_apply_assistant/workflows.py +435 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting Vulnerabilities
|
|
4
|
+
|
|
5
|
+
Use GitHub private vulnerability reporting for the standalone project when available.
|
|
6
|
+
|
|
7
|
+
If private reporting is not configured yet, open a maintainer-private channel before sharing exploit details publicly. A standalone security contact can be added here when the public repository is configured.
|
|
8
|
+
|
|
9
|
+
Do not use upstream personal contacts as the default standalone package security contact.
|
|
10
|
+
|
|
11
|
+
## Reporting Routes
|
|
12
|
+
|
|
13
|
+
- Usage and setup support belongs in [SUPPORT.md](SUPPORT.md).
|
|
14
|
+
- Public safety/compliance concerns can use [.github/ISSUE_TEMPLATE/safety_compliance.yml](.github/ISSUE_TEMPLATE/safety_compliance.yml) only without exploit details.
|
|
15
|
+
- Conduct reports belong in [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) and should use private reporting.
|
|
16
|
+
- Vulnerability details stay in this security policy and should not be posted publicly.
|
|
17
|
+
|
|
18
|
+
## What to Report
|
|
19
|
+
|
|
20
|
+
Report issues such as:
|
|
21
|
+
|
|
22
|
+
- credential or token exposure
|
|
23
|
+
- browser profile leakage
|
|
24
|
+
- report redaction failures
|
|
25
|
+
- unsafe submit behavior
|
|
26
|
+
- dependency vulnerabilities
|
|
27
|
+
- documentation that encourages unsafe platform behavior
|
|
28
|
+
|
|
29
|
+
## Local Secret and Browser Profile Safety
|
|
30
|
+
|
|
31
|
+
Keep local config, Q&A banks, visible-browser profiles, outputs, reports, and private documents out of version control. The package `.gitignore` contains the expected local runtime patterns.
|
|
32
|
+
|
|
33
|
+
Never attach browser profiles, cookies, credentials, screenshots, private documents, generated local reports, or full private URLs to public issues.
|
|
34
|
+
|
|
35
|
+
## Supported Versions
|
|
36
|
+
|
|
37
|
+
The initial standalone GitHub source release is `0.1.0`. Current package metadata is `0.1.1`. Security guidance applies to the current unreleased, `0.1.1`, and `0.1.0` package-local surfaces.
|
package/SUPPORT.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Support
|
|
2
|
+
|
|
3
|
+
LinkedIn-apply-assistant support is for the standalone local package and its
|
|
4
|
+
documented source, Python, and npm launcher workflows.
|
|
5
|
+
|
|
6
|
+
## Before Opening an Issue
|
|
7
|
+
|
|
8
|
+
Start with [README.md](README.md) and
|
|
9
|
+
[docs/troubleshooting.md](docs/troubleshooting.md). For setup questions, run:
|
|
10
|
+
|
|
11
|
+
```powershell
|
|
12
|
+
linkedin-apply-assistant config check
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Use the config/help issue form only after removing private local details.
|
|
16
|
+
|
|
17
|
+
## Public Support Routes
|
|
18
|
+
|
|
19
|
+
- Reproducible bugs: open a GitHub issue with the sanitized command, package
|
|
20
|
+
version or source commit, operating system, Python version, expected result,
|
|
21
|
+
actual result, and minimal reproduction steps.
|
|
22
|
+
- Feature requests: describe the problem, proposed behavior, workflow impact,
|
|
23
|
+
safety/privacy impact, and alternatives considered.
|
|
24
|
+
- Documentation issues: name the affected page or link, explain what is stale
|
|
25
|
+
or confusing, and suggest the correction.
|
|
26
|
+
|
|
27
|
+
GitHub Discussions are not enabled for this repository in Phase 26.
|
|
28
|
+
|
|
29
|
+
## Sensitive Routes
|
|
30
|
+
|
|
31
|
+
- Vulnerabilities belong in [SECURITY.md](SECURITY.md). Do not post exploit
|
|
32
|
+
details publicly.
|
|
33
|
+
- Safety or platform-compliance concerns can use the safety/compliance issue
|
|
34
|
+
form only when the concern can be described without exploit details or private
|
|
35
|
+
data.
|
|
36
|
+
- Conduct reports belong in [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) and should
|
|
37
|
+
use a maintainer-private channel placeholder until a dedicated private contact
|
|
38
|
+
is configured.
|
|
39
|
+
|
|
40
|
+
## Do Not Post Private Data
|
|
41
|
+
|
|
42
|
+
Do not post credentials, cookies, browser profiles, screenshots, CVs, private
|
|
43
|
+
documents, generated local reports, full private URLs, or live job history in
|
|
44
|
+
public issues, pull requests, or discussions.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
This file records attribution and notice information for the standalone package. It is an engineering notice artifact, not legal advice.
|
|
4
|
+
|
|
5
|
+
## Career-Ops
|
|
6
|
+
|
|
7
|
+
Some implementation and documentation history was extracted from or derived from Career-Ops, an MIT-licensed project by Santiago Fernandez de Valderrama.
|
|
8
|
+
|
|
9
|
+
Career-Ops is mentioned here only for neutral attribution and provenance. LinkedIn-apply-assistant is the standalone package identity.
|
|
10
|
+
|
|
11
|
+
MIT notice:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
MIT License
|
|
15
|
+
|
|
16
|
+
Copyright (c) 2026 Santiago Fernandez de Valderrama
|
|
17
|
+
|
|
18
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
20
|
+
in the Software without restriction, including without limitation the rights
|
|
21
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
22
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
23
|
+
furnished to do so, subject to the following conditions:
|
|
24
|
+
|
|
25
|
+
The above copyright notice and this permission notice shall be included in all
|
|
26
|
+
copies or substantial portions of the Software.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Scrapling
|
|
30
|
+
|
|
31
|
+
Scrapling is a normal Python dependency of this package. It is not the product identity and is not an endorsement claim.
|
|
32
|
+
|
|
33
|
+
License verification source checked during Phase 18 execution: official upstream repository license at `https://raw.githubusercontent.com/D4Vinci/Scrapling/main/LICENSE`. The upstream license identifies Scrapling as BSD 3-Clause, copyright 2024 Karim shoair.
|
|
34
|
+
|
|
35
|
+
BSD 3-Clause notice:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
BSD 3-Clause License
|
|
39
|
+
|
|
40
|
+
Copyright (c) 2024, Karim shoair
|
|
41
|
+
|
|
42
|
+
Redistribution and use in source and binary forms, with or without
|
|
43
|
+
modification, are permitted provided that the following conditions are met:
|
|
44
|
+
|
|
45
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
46
|
+
list of conditions and the following disclaimer.
|
|
47
|
+
|
|
48
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
49
|
+
this list of conditions and the following disclaimer in the documentation
|
|
50
|
+
and/or other materials provided with the distribution.
|
|
51
|
+
|
|
52
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
53
|
+
may be used to endorse or promote products derived from this software without
|
|
54
|
+
specific prior written permission.
|
|
55
|
+
|
|
56
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
57
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
58
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
59
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
60
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
61
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
62
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
63
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
64
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
65
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
66
|
+
```
|
|
67
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { dirname, delimiter, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const cliModule = "linkedin_apply_assistant.cli";
|
|
9
|
+
const userArgs = process.argv.slice(2);
|
|
10
|
+
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const packageRoot = resolve(scriptDir, "..");
|
|
12
|
+
const localSrc = resolve(scriptDir, "..", "src");
|
|
13
|
+
const launcherEnv = { ...process.env };
|
|
14
|
+
const candidates =
|
|
15
|
+
process.platform === "win32"
|
|
16
|
+
? [
|
|
17
|
+
["py", ["-3"]],
|
|
18
|
+
["python", []],
|
|
19
|
+
["python3", []],
|
|
20
|
+
]
|
|
21
|
+
: [
|
|
22
|
+
["python3", []],
|
|
23
|
+
["python", []],
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
if (existsSync(localSrc)) {
|
|
27
|
+
launcherEnv.PYTHONPATH = launcherEnv.PYTHONPATH
|
|
28
|
+
? `${localSrc}${delimiter}${launcherEnv.PYTHONPATH}`
|
|
29
|
+
: localSrc;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function printSetupGuidance(reason) {
|
|
33
|
+
console.error(`linkedin-apply-assistant npm launcher could not start: ${reason}`);
|
|
34
|
+
console.error("");
|
|
35
|
+
console.error("This npm package is only a thin launcher for the Python package.");
|
|
36
|
+
console.error("Install the bundled Python package from this npm package root, then retry:");
|
|
37
|
+
console.error(` python -m pip install "${packageRoot}"`);
|
|
38
|
+
console.error(` py -3 -m pip install "${packageRoot}"`);
|
|
39
|
+
console.error("");
|
|
40
|
+
console.error("Module fallback after source checkout:");
|
|
41
|
+
console.error(" python -m linkedin_apply_assistant.cli --help");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function runPython(command, args, options = {}) {
|
|
45
|
+
return spawnSync(command, args, {
|
|
46
|
+
env: launcherEnv,
|
|
47
|
+
windowsHide: true,
|
|
48
|
+
...options,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let sawPython = false;
|
|
53
|
+
|
|
54
|
+
for (const [command, prefixArgs] of candidates) {
|
|
55
|
+
const probe = runPython(command, [...prefixArgs, "-c", `import ${cliModule}`], {
|
|
56
|
+
stdio: "ignore",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (probe.error?.code === "ENOENT") {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (probe.error) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
sawPython = true;
|
|
68
|
+
|
|
69
|
+
if (probe.status !== 0) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const result = runPython(command, [...prefixArgs, "-m", cliModule, ...userArgs], {
|
|
74
|
+
stdio: "inherit",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (result.error) {
|
|
78
|
+
printSetupGuidance(result.error.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (result.signal) {
|
|
83
|
+
console.error(`Python CLI exited after signal ${result.signal}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
process.exit(result.status ?? 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
printSetupGuidance(
|
|
91
|
+
sawPython
|
|
92
|
+
? "Python was found, but the linkedin_apply_assistant package is not importable."
|
|
93
|
+
: "No usable Python executable was found on PATH.",
|
|
94
|
+
);
|
|
95
|
+
process.exit(1);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
profile:
|
|
2
|
+
name: "Example Candidate"
|
|
3
|
+
headline: "Software engineer"
|
|
4
|
+
location: "Example City"
|
|
5
|
+
contact:
|
|
6
|
+
email: "candidate@example.com"
|
|
7
|
+
phone: null
|
|
8
|
+
website: "https://example.com/portfolio"
|
|
9
|
+
|
|
10
|
+
defaults:
|
|
11
|
+
limit: 10
|
|
12
|
+
visible_browser: true
|
|
13
|
+
require_confirmation: true
|
|
14
|
+
dry_run: true
|
|
15
|
+
|
|
16
|
+
documents:
|
|
17
|
+
resume: "documents/resume.example.pdf"
|
|
18
|
+
cover_letter: "documents/cover-letter.example.pdf"
|
|
19
|
+
portfolio: "https://example.com/portfolio"
|
|
20
|
+
|
|
21
|
+
paths:
|
|
22
|
+
qa_bank: "configs/qa_bank.example.yml"
|
|
23
|
+
browser_profile: null
|
|
24
|
+
output_dir: "local-output"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
qa_pairs:
|
|
2
|
+
- id: work_authorization
|
|
3
|
+
question_patterns:
|
|
4
|
+
- "Are you authorized to work in the target country?"
|
|
5
|
+
- "Do you require sponsorship?"
|
|
6
|
+
answer: "Use a truthful work-authorization answer for your situation."
|
|
7
|
+
response_type: text
|
|
8
|
+
|
|
9
|
+
- id: notice_period
|
|
10
|
+
question_patterns:
|
|
11
|
+
- "When can you start?"
|
|
12
|
+
- "What is your notice period?"
|
|
13
|
+
answer: "Use your current availability or notice period."
|
|
14
|
+
response_type: text
|
|
15
|
+
|
|
16
|
+
- id: work_arrangement
|
|
17
|
+
question_patterns:
|
|
18
|
+
- "Do you prefer remote, hybrid, or onsite work?"
|
|
19
|
+
- "What work arrangement are you looking for?"
|
|
20
|
+
answer: "Remote or hybrid roles are preferred, depending on team needs."
|
|
21
|
+
response_type: text
|
|
22
|
+
|
|
23
|
+
- id: compensation_expectation
|
|
24
|
+
question_patterns:
|
|
25
|
+
- "What are your salary expectations?"
|
|
26
|
+
- "What compensation range are you targeting?"
|
|
27
|
+
answer: "Use a realistic range for the role, location, and market."
|
|
28
|
+
response_type: text
|
|
29
|
+
|
|
30
|
+
- id: portfolio
|
|
31
|
+
question_patterns:
|
|
32
|
+
- "Please share a portfolio or project link."
|
|
33
|
+
- "Do you have examples of your work?"
|
|
34
|
+
answer: "https://example.com/portfolio"
|
|
35
|
+
response_type: url
|
package/docs/apply.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Prepare-Only Apply Workflow
|
|
2
|
+
|
|
3
|
+
`apply` prepares local application audit output from candidate job input. Browser submission remains disabled in the current public package.
|
|
4
|
+
|
|
5
|
+
## Prepare From Input
|
|
6
|
+
|
|
7
|
+
Use synthetic or local candidate job input:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
linkedin-apply-assistant apply --input examples\dry_run_input.example.json --limit 1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The input file should not contain credentials, private documents, browser state, screenshots, full private URLs, or live job history.
|
|
14
|
+
|
|
15
|
+
## Guarded Future Option
|
|
16
|
+
|
|
17
|
+
The CLI exposes `--confirm-submit` as a guarded future option:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
linkedin-apply-assistant apply --input examples\dry_run_input.example.json --limit 1 --confirm-submit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Current browser submission remains disabled. Any future submit-capable release must still require explicit per-submission confirmation immediately before a specific application is sent, and must preserve the safety guardrails described in [../SAFETY.md](../SAFETY.md).
|
|
24
|
+
|
|
25
|
+
## Shared Options
|
|
26
|
+
|
|
27
|
+
`apply` accepts:
|
|
28
|
+
|
|
29
|
+
- `--workspace`
|
|
30
|
+
- `--config`
|
|
31
|
+
- `--qa-bank`
|
|
32
|
+
- `--browser-profile`
|
|
33
|
+
- `--output-dir`
|
|
34
|
+
- `--verbose`
|
|
35
|
+
- `--input`
|
|
36
|
+
- `--limit`
|
|
37
|
+
- `--confirm-submit`
|
|
38
|
+
|
|
39
|
+
Do not use `apply` for mass applications, unattended apply sessions, fake answers, CAPTCHA or MFA bypass, or continued automation after platform risk signals.
|
|
40
|
+
|
package/docs/assist.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Assistive Fill-Only Workflow
|
|
2
|
+
|
|
3
|
+
`assist` opens a visible-browser workflow where the user drives the session and the assistant fills supported fields. It is a fill-only boundary.
|
|
4
|
+
|
|
5
|
+
## On-Demand Mode
|
|
6
|
+
|
|
7
|
+
Use on-demand mode when you want to control each fill attempt:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
linkedin-apply-assistant assist --mode on-demand --max-cycles 3
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Auto-Watch Mode
|
|
14
|
+
|
|
15
|
+
Use auto-watch when you want the assistant to inspect detected fillable surfaces:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
linkedin-apply-assistant assist --mode auto-watch --max-cycles 3
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Start Page
|
|
22
|
+
|
|
23
|
+
```powershell
|
|
24
|
+
linkedin-apply-assistant assist --start-url "https://www.linkedin.com/jobs/" --mode on-demand
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Boundaries
|
|
28
|
+
|
|
29
|
+
- You remain responsible for the browser session.
|
|
30
|
+
- Unknown required questions should stop until you provide a truthful answer.
|
|
31
|
+
- The assistant must not submit applications in this workflow.
|
|
32
|
+
- The assistant must not continue through CAPTCHA, MFA, checkpoints, platform throttling, or similar risk signals.
|
|
33
|
+
|
|
34
|
+
For browser profile safety, see [browser-session.md](browser-session.md).
|
|
35
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Visible Browser Session Setup
|
|
2
|
+
|
|
3
|
+
Browser workflows are local and user-visible. You drive or review the browser session; the package does not run hidden unattended apply workflows.
|
|
4
|
+
|
|
5
|
+
## Browser Profile
|
|
6
|
+
|
|
7
|
+
Use `--browser-profile` to choose a local profile directory:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
linkedin-apply-assistant --browser-profile .\local-workspace\browser-profile assist --mode on-demand
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The profile can contain cookies, sessions, and local form state. Keep it ignored, local, and under your control. Do not copy it into examples, issues, fixtures, or reports.
|
|
14
|
+
|
|
15
|
+
## Login Flow
|
|
16
|
+
|
|
17
|
+
Open a visible browser session and log in yourself when the platform asks for it. If a checkpoint, rate limit, MFA prompt, or other platform risk signal appears, stop and resolve it manually.
|
|
18
|
+
|
|
19
|
+
The assistant must not bypass CAPTCHA, MFA, checkpoints, platform throttling, or employer application rules.
|
|
20
|
+
|
|
21
|
+
## Start URL
|
|
22
|
+
|
|
23
|
+
Use `assist --start-url` when you want the visible browser to open a specific starting page:
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
linkedin-apply-assistant assist --start-url "https://www.linkedin.com/jobs/" --mode on-demand
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Only use URLs you are comfortable opening in your own browser session. Do not publish full private application URLs in docs or examples.
|
|
30
|
+
|
|
31
|
+
## Session Modes
|
|
32
|
+
|
|
33
|
+
`assist` supports:
|
|
34
|
+
|
|
35
|
+
- `--mode on-demand`: inspect/fill only when requested by the user workflow.
|
|
36
|
+
- `--mode auto-watch`: watch for fillable surfaces and fill once per detected surface.
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
|
|
40
|
+
```powershell
|
|
41
|
+
linkedin-apply-assistant assist --mode auto-watch --max-cycles 3
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Both modes remain fill-only boundaries. They do not submit applications.
|
|
45
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# CI and Release Policy
|
|
2
|
+
|
|
3
|
+
This repository uses CI to make public project health visible without creating
|
|
4
|
+
tags, GitHub Releases, package uploads, registry tokens, attestations, or
|
|
5
|
+
repository-setting changes.
|
|
6
|
+
|
|
7
|
+
## Workflows
|
|
8
|
+
|
|
9
|
+
Two user-authored GitHub Actions workflows are expected on `main`:
|
|
10
|
+
|
|
11
|
+
- `Quality` at `.github/workflows/quality.yml`
|
|
12
|
+
- `Security` at `.github/workflows/security.yml`
|
|
13
|
+
|
|
14
|
+
Both workflows run on pull requests, pushes to `main`, and manual dispatch. Only
|
|
15
|
+
`Security` has a weekly scheduled scan. Both workflows use concurrency with
|
|
16
|
+
`cancel-in-progress` so stale branch runs do not consume runner capacity.
|
|
17
|
+
|
|
18
|
+
## Quality
|
|
19
|
+
|
|
20
|
+
The `Quality` workflow has two jobs:
|
|
21
|
+
|
|
22
|
+
- `quality` runs on Ubuntu with Python `3.11` and `3.12`.
|
|
23
|
+
- `release-smoke` runs once with Python `3.12` and Node.js `24`.
|
|
24
|
+
|
|
25
|
+
The workflow installs Python dependencies with:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python -m pip install -e ".[dev]"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It does not require `npm ci` because the package does not currently ship a
|
|
32
|
+
standalone lockfile. The release-smoke job validates the release manifest, runs
|
|
33
|
+
focused release-readiness tests, runs `python scripts/release.py verify`, and
|
|
34
|
+
checks npm launcher package shape with `npm pack --dry-run --json`.
|
|
35
|
+
|
|
36
|
+
The CI suite intentionally stays browser-free. It does not run live LinkedIn,
|
|
37
|
+
browser-profile, final-submit, or user-layer-file workflows.
|
|
38
|
+
|
|
39
|
+
## Security
|
|
40
|
+
|
|
41
|
+
The `Security` workflow has three jobs:
|
|
42
|
+
|
|
43
|
+
- `codeql` runs committed CodeQL advanced setup for Python and JavaScript only,
|
|
44
|
+
with `security-extended` queries.
|
|
45
|
+
- `dependency-review` runs only on pull requests and fails on high or critical
|
|
46
|
+
dependency risk through `fail-on-severity: high`.
|
|
47
|
+
- `secret-scan` runs Gitleaks against the checked-out repository history.
|
|
48
|
+
|
|
49
|
+
Workflow permissions default to `contents: read`. The only write permission is
|
|
50
|
+
`security-events: write`, and it is limited to the CodeQL job.
|
|
51
|
+
The Gitleaks step receives the default `GITHUB_TOKEN` only for action API access
|
|
52
|
+
and sets `GITLEAKS_ENABLE_COMMENTS=false`, so it does not need pull-request write
|
|
53
|
+
permissions.
|
|
54
|
+
|
|
55
|
+
Phase 28 deliberately does not add Bandit, Semgrep, or another extra SAST tool.
|
|
56
|
+
Dependabot covers GitHub Actions, npm, and pip at repository root `/` with
|
|
57
|
+
weekly grouped updates, open pull request limit `5`, and no auto-merge. Labels
|
|
58
|
+
and assignees are skipped unless maintainers add a label policy later.
|
|
59
|
+
|
|
60
|
+
## Release Automation Boundary
|
|
61
|
+
|
|
62
|
+
This project currently uses manual GitHub source releases. Phase 28 does not
|
|
63
|
+
enable Release Please, semantic-release, tag automation, changelog automation,
|
|
64
|
+
or any equivalent release writer.
|
|
65
|
+
|
|
66
|
+
Conventional Commits are recommended for maintainability, but CI does not
|
|
67
|
+
enforce commit-message format.
|
|
68
|
+
|
|
69
|
+
The workflows and Dependabot config are source-release metadata. They are kept
|
|
70
|
+
in `release-manifest.json` for source-checkout visibility, but workflow files
|
|
71
|
+
and `.github/dependabot.yml` are excluded from npm package contents unless a
|
|
72
|
+
future phase intentionally documents otherwise.
|
|
73
|
+
|
|
74
|
+
## Deferred Provenance Work
|
|
75
|
+
|
|
76
|
+
The following controls are feasible future work, not active behavior:
|
|
77
|
+
|
|
78
|
+
- SBOM generation, after a real artifact channel is selected.
|
|
79
|
+
- Artifact attestations, after the project intentionally grants
|
|
80
|
+
`id-token: write` and `attestations: write`.
|
|
81
|
+
- Signing and immutable-release policy, after release assets or package
|
|
82
|
+
channels exist.
|
|
83
|
+
- Trusted publisher setup or package-name reservation, in a dedicated registry
|
|
84
|
+
publication phase.
|
|
85
|
+
|
|
86
|
+
The future registry channel order, trusted-publishing boundary, approval
|
|
87
|
+
templates, and rollback limits are documented in the
|
|
88
|
+
[registry publication strategy](registry-publication-strategy.md).
|
|
89
|
+
|
|
90
|
+
No Phase 28 workflow grants `packages: write`, `id-token: write`, or
|
|
91
|
+
`attestations: write`.
|
|
92
|
+
|
|
93
|
+
## No-Surprise Publish Boundary
|
|
94
|
+
|
|
95
|
+
Phase 28 automation must not:
|
|
96
|
+
|
|
97
|
+
- run `npm publish`
|
|
98
|
+
- run `twine upload`
|
|
99
|
+
- create, edit, delete, or upload a GitHub Release
|
|
100
|
+
- create or push tags
|
|
101
|
+
- reserve package names
|
|
102
|
+
- configure trusted publishers
|
|
103
|
+
- mutate branch rulesets, tag rulesets, required checks, or repository settings
|
|
104
|
+
|
|
105
|
+
Public sync and live workflow verification remain explicit maintainer actions.
|