@epsilon-asi/actors 0.0.3 → 0.0.5
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/.ai/generators/_template.ts +37 -0
- package/.ai/generators/abstract.ts +24 -0
- package/.ai/generators/actor-task-form-filler.ts +140 -0
- package/.ai/generators/actor-task.ts +122 -0
- package/.ai/generators/auth-core.ts +126 -0
- package/.ai/generators/browser-runtime.ts +114 -0
- package/.ai/generators/cli-command.ts +96 -0
- package/.ai/generators/core-framework.ts +80 -0
- package/.ai/generators/docs.ts +92 -0
- package/.ai/generators/error-logging.ts +102 -0
- package/.ai/generators/extraction-helper.ts +96 -0
- package/.ai/generators/interaction-behavior.ts +129 -0
- package/.ai/generators/site-actor.ts +125 -0
- package/.ai/generators/site-login-flow.ts +117 -0
- package/.ai/generators/unit-test.ts +109 -0
- package/.ai/workflows/_template.ts +20 -0
- package/.ai/workflows/starter.ts +20 -0
- package/ai-gen.config.ts +67 -0
- package/package.json +4 -12
- package/src/auth/AuthStateDetector.ts +18 -0
- package/src/auth/CredentialsProvider.ts +48 -0
- package/src/auth/LoginFlow.ts +332 -0
- package/src/auth/LoginFlow.types.ts +141 -0
- package/src/auth/SessionStore.ts +21 -0
- package/src/auth/index.ts +5 -0
- package/src/browser/BrowserFactory.ts +253 -0
- package/src/browser/BrowserSession.ts +50 -0
- package/src/browser/PuppeteerLike.ts +65 -0
- package/src/browser/RuntimeConfig.ts +152 -0
- package/src/browser/index.ts +5 -0
- package/src/browser/profileValidation.ts +73 -0
- package/src/cli/run.ts +112 -0
- package/src/core/Actor.ts +167 -0
- package/src/core/ActorContext.ts +34 -0
- package/src/core/ActorRegistry.ts +26 -0
- package/src/core/ActorRunner.ts +240 -0
- package/src/core/defineActor.ts +5 -0
- package/src/core/index.ts +5 -0
- package/src/errors/AuthError.ts +7 -0
- package/src/errors/AutomationError.ts +26 -0
- package/src/errors/ConfigError.ts +7 -0
- package/src/errors/ExtractionError.ts +7 -0
- package/src/errors/NavigationError.ts +7 -0
- package/src/errors/SelectorError.ts +10 -0
- package/src/errors/index.ts +6 -0
- package/src/extraction/Extractor.ts +65 -0
- package/src/extraction/Pagination.ts +47 -0
- package/src/extraction/index.ts +2 -0
- package/src/index.ts +9 -0
- package/src/interaction/FieldClearer.ts +73 -0
- package/src/interaction/Forms.ts +27 -0
- package/src/interaction/GhostCursorAdapter.ts +79 -0
- package/src/interaction/HumanInteractor.ts +32 -0
- package/src/interaction/HumanTyping.ts +157 -0
- package/src/interaction/NativePuppeteerInteractor.ts +68 -0
- package/src/interaction/Navigation.ts +37 -0
- package/src/interaction/PageAdapter.ts +86 -0
- package/src/interaction/Waits.ts +5 -0
- package/src/interaction/index.ts +9 -0
- package/src/logging/ConsoleLogger.ts +44 -0
- package/src/logging/Logger.ts +15 -0
- package/src/logging/MemoryLogger.ts +34 -0
- package/src/logging/NullLogger.ts +8 -0
- package/src/logging/index.ts +4 -0
- package/src/sites/example/example.actor.ts +53 -0
- package/src/sites/example/example.selectors.ts +17 -0
- package/src/sites/example/example.types.ts +18 -0
- package/src/sites/example/index.ts +3 -0
- package/src/sites/index.ts +3 -0
- package/src/sites/myvistage-com/index.ts +3 -0
- package/src/sites/myvistage-com/login-action-list.json +349 -0
- package/src/sites/myvistage-com/myvistage-com.actor.ts +50 -0
- package/src/sites/myvistage-com/myvistage-com.selectors.ts +14 -0
- package/src/sites/myvistage-com/myvistage-com.types.ts +18 -0
- package/src/sites/myvistage-com/post-comment-action.json +81 -0
- package/src/sites/upwork-com/index.ts +6 -0
- package/src/sites/upwork-com/upwork-com.actor.ts +97 -0
- package/src/sites/upwork-com/upwork-com.runner.ts +17 -0
- package/src/sites/upwork-com/upwork-com.selectors.ts +10 -0
- package/src/sites/upwork-com/upwork-com.types.ts +102 -0
- package/src/sites/upwork-com/upwork-com.util.ts +41 -0
- package/src/utils/delay.ts +4 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/invariant.ts +7 -0
- package/src/utils/redact.ts +53 -0
- package/src/utils/retry.ts +31 -0
- package/src/utils/url.ts +7 -0
- package/tests/fixtures/FakeCredentialsProvider.ts +12 -0
- package/tests/fixtures/FakeCursor.ts +48 -0
- package/tests/fixtures/FakePage.ts +266 -0
- package/tests/fixtures/makeContext.ts +76 -0
- package/tests/unit/auth/AuthStateDetector.test.ts +80 -0
- package/tests/unit/auth/LoginFlow.test.ts +296 -0
- package/tests/unit/browser/BrowserFactory.test.ts +370 -0
- package/tests/unit/core/ActorRunner.test.ts +370 -0
- package/tests/unit/core/defineActor.test.ts +112 -0
- package/tests/unit/extraction/Extractor.test.ts +48 -0
- package/tests/unit/extraction/Pagination.test.ts +54 -0
- package/tests/unit/interaction/FieldClearer.test.ts +29 -0
- package/tests/unit/interaction/Forms.test.ts +35 -0
- package/tests/unit/interaction/GhostCursorAdapter.test.ts +68 -0
- package/tests/unit/interaction/HumanTyping.test.ts +54 -0
- package/tests/unit/interaction/NativePuppeteerInteractor.test.ts +22 -0
- package/tests/unit/interaction/PageAdapter.test.ts +25 -0
- package/tests/unit/logging/redact.test.ts +36 -0
- package/tests/unit/sites/myvistage-com.actor.test.ts +19 -0
- package/tests/unit/sites/myvistage-com.login.test.ts +22 -0
- package/tests/unit/sites/myvistage-com.postComment.test.ts +70 -0
- package/tests/unit/sites/upwork-com.login.test.ts +52 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: 'site-login-flow',
|
|
3
|
+
description: 'Add or revise a site actor login flow, including simple, staged, and multi-step username/password flows.',
|
|
4
|
+
instructions: `
|
|
5
|
+
Update the site auth configuration using defineLoginFlow.
|
|
6
|
+
|
|
7
|
+
Rules:
|
|
8
|
+
- Keep login configuration inside the site actor unless the repo already split auth into a separate file.
|
|
9
|
+
- Use selectors.loggedInSignal for post-login verification.
|
|
10
|
+
- Use selectors.errorMessage when the site exposes a visible error message.
|
|
11
|
+
- For one-page login forms, selectors.username/password/submit are acceptable.
|
|
12
|
+
- For staged forms, use the ordered steps array.
|
|
13
|
+
- For username-first/password-second forms, use fill(username), click(continue with waitForSelector), fill(password), click(submit).
|
|
14
|
+
- Preserve clearFieldBeforeTyping defaults unless the user explicitly requests otherwise.
|
|
15
|
+
- Preserve human-like typing behavior through behavior.typing or per-fill-step typing overrides.
|
|
16
|
+
- Use credential: 'username' and credential: 'password' for credential fields.
|
|
17
|
+
- Use value or a value resolver only for non-credential fields, such as tenant/workspace/account id.
|
|
18
|
+
- Add waitForSelector after intermediate click steps whenever the next field appears asynchronously.
|
|
19
|
+
- Mark the final click step with submit: true so beforeSubmit/afterSubmit hooks apply.
|
|
20
|
+
- Add or update tests for the login shape and any custom hook/step behavior.
|
|
21
|
+
|
|
22
|
+
DO NOT hard-code real usernames, passwords, tokens, cookies, or private profile paths.
|
|
23
|
+
DO NOT implement CAPTCHA bypass or anti-bot circumvention.
|
|
24
|
+
`.trim(),
|
|
25
|
+
output: {
|
|
26
|
+
pathTemplates: [
|
|
27
|
+
{
|
|
28
|
+
key: 'actor',
|
|
29
|
+
pathTemplate: 'src/sites/{{siteKebab}}/{{siteKebab}}.actor.ts',
|
|
30
|
+
description: 'The site actor whose auth definition should be added or updated.'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
key: 'selectors',
|
|
34
|
+
pathTemplate: 'src/sites/{{siteKebab}}/{{siteKebab}}.selectors.ts',
|
|
35
|
+
description: 'Selectors for login fields, buttons, errors, and logged-in signals.'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'tests',
|
|
39
|
+
pathTemplate: 'tests/unit/sites/{{siteKebab}}.login.test.ts',
|
|
40
|
+
description: 'Focused tests for the generated site login config or custom login behavior.'
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
maxFiles: 3
|
|
44
|
+
},
|
|
45
|
+
parameters: {
|
|
46
|
+
site: {
|
|
47
|
+
description: 'The site whose login should be implemented or edited.',
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
loginUrl: {
|
|
51
|
+
description: 'Login URL or path for the site.',
|
|
52
|
+
required: false
|
|
53
|
+
},
|
|
54
|
+
flowType: {
|
|
55
|
+
description: 'Login flow style, for example simple, multi-step, username-first, tenant-first, or custom.',
|
|
56
|
+
required: false
|
|
57
|
+
},
|
|
58
|
+
instructions: {
|
|
59
|
+
description: 'Selectors, step order, waits, hooks, and edge cases for this login form.',
|
|
60
|
+
required: false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
examples: [
|
|
64
|
+
'src/sites/example/example.actor.ts',
|
|
65
|
+
'src/sites/example/example.selectors.ts',
|
|
66
|
+
'tests/unit/auth/LoginFlow.test.ts'
|
|
67
|
+
],
|
|
68
|
+
context: [
|
|
69
|
+
{
|
|
70
|
+
kind: 'path',
|
|
71
|
+
path: 'src/sites/{{siteKebab}}/{{siteKebab}}.actor.ts',
|
|
72
|
+
description: 'Existing site actor to update when present.',
|
|
73
|
+
required: false
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
kind: 'path',
|
|
77
|
+
path: 'src/sites/{{siteKebab}}/{{siteKebab}}.selectors.ts',
|
|
78
|
+
description: 'Existing site selectors to update when present.',
|
|
79
|
+
required: false
|
|
80
|
+
},
|
|
81
|
+
{ kind: 'path', path: 'src/auth/LoginFlow.types.ts', description: 'LoginFlowDefinition and LoginStep types.' },
|
|
82
|
+
{ kind: 'path', path: 'src/auth/LoginFlow.ts', description: 'How login steps execute.' },
|
|
83
|
+
{ kind: 'path', path: 'src/auth/CredentialsProvider.ts', description: 'Credential references and providers.' },
|
|
84
|
+
{ kind: 'path', path: 'src/auth/AuthStateDetector.ts', description: 'Logged-in detection behavior.' },
|
|
85
|
+
{ kind: 'path', path: 'src/interaction/Forms.ts', description: 'Form filling behavior used by fill steps.' },
|
|
86
|
+
{ kind: 'path', path: 'src/interaction/FieldClearer.ts', description: 'clearFieldBeforeTyping implementation.' },
|
|
87
|
+
{ kind: 'path', path: 'src/interaction/HumanTyping.ts', description: 'Human-like typing options used by login fill steps.' },
|
|
88
|
+
{ kind: 'path', path: 'tests/unit/auth/LoginFlow.test.ts', description: 'Canonical login flow tests.' }
|
|
89
|
+
],
|
|
90
|
+
keywordContexts: [
|
|
91
|
+
{
|
|
92
|
+
keywords: ['multi-step', 'multistep', 'apple', 'upwork', 'continue', 'next', 'waitForSelector'],
|
|
93
|
+
context: [
|
|
94
|
+
{ kind: 'path', path: 'tests/unit/auth/LoginFlow.test.ts', description: 'Contains multi-step login expectations.' },
|
|
95
|
+
{ kind: 'path', path: 'src/auth/LoginFlow.types.ts', description: 'Step-specific wait and hook options.' }
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
keywords: ['clearFieldBeforeTyping', 'clear', 'pre-filled', 'select-delete'],
|
|
100
|
+
context: [
|
|
101
|
+
{ kind: 'path', path: 'tests/unit/interaction/FieldClearer.test.ts', description: 'Field clearing behavior tests.' }
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
keywords: ['typing', 'wpm', 'human-like', 'jitter'],
|
|
106
|
+
context: [
|
|
107
|
+
{ kind: 'path', path: 'tests/unit/interaction/HumanTyping.test.ts', description: 'Typing timing tests.' },
|
|
108
|
+
{ kind: 'path', path: 'tests/unit/interaction/NativePuppeteerInteractor.test.ts', description: 'Typing integration tests.' }
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
tooling: {
|
|
113
|
+
allowGetExistingCode: true,
|
|
114
|
+
allowFindFiles: true,
|
|
115
|
+
allowSearchRepo: true
|
|
116
|
+
}
|
|
117
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: 'unit-test',
|
|
3
|
+
description: 'Generate or update Vitest unit tests for framework modules, site actors, and test fixtures.',
|
|
4
|
+
instructions: `
|
|
5
|
+
Write deterministic Vitest unit tests that match the repo style.
|
|
6
|
+
|
|
7
|
+
Rules:
|
|
8
|
+
- Use Vitest APIs and existing test structure under tests/unit.
|
|
9
|
+
- Prefer FakePage, FakeCursor, FakeCredentialsProvider, and makeContext over live browser tests.
|
|
10
|
+
- Do not launch Chrome in unit tests.
|
|
11
|
+
- Test observable behavior, calls, returned data, and typed errors.
|
|
12
|
+
- Cover success and failure paths for core/auth/browser changes.
|
|
13
|
+
- Keep fixtures minimal and reusable.
|
|
14
|
+
- If a source change requires fixture updates, update the fixture in the same result.
|
|
15
|
+
- Match strict TypeScript settings; avoid any unless the existing test pattern requires it.
|
|
16
|
+
|
|
17
|
+
DO NOT write brittle tests that depend on real websites, external network, or a user profile path.
|
|
18
|
+
`.trim(),
|
|
19
|
+
output: {
|
|
20
|
+
pathTemplates: [
|
|
21
|
+
{
|
|
22
|
+
key: 'test',
|
|
23
|
+
pathTemplate: 'tests/unit/{{areaKebab}}/{{subjectPascal}}.test.ts',
|
|
24
|
+
description: 'Unit test file for the requested area and subject.'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'fake-page',
|
|
28
|
+
pathTemplate: 'tests/fixtures/FakePage.ts',
|
|
29
|
+
description: 'Update only when page behavior required by the tests is missing.'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'fake-cursor',
|
|
33
|
+
pathTemplate: 'tests/fixtures/FakeCursor.ts',
|
|
34
|
+
description: 'Update only when cursor behavior required by the tests is missing.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'fake-credentials',
|
|
38
|
+
pathTemplate: 'tests/fixtures/FakeCredentialsProvider.ts',
|
|
39
|
+
description: 'Update only when credential behavior required by the tests is missing.'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: 'make-context',
|
|
43
|
+
pathTemplate: 'tests/fixtures/makeContext.ts',
|
|
44
|
+
description: 'Update only when ActorContext construction changes.'
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
maxFiles: 5
|
|
48
|
+
},
|
|
49
|
+
parameters: {
|
|
50
|
+
area: {
|
|
51
|
+
description: 'Test area folder, for example auth, browser, core, extraction, interaction, logging, sites, or cli.',
|
|
52
|
+
required: true
|
|
53
|
+
},
|
|
54
|
+
subject: {
|
|
55
|
+
description: 'Class/function/component under test, for example LoginFlow, BrowserFactory, or HumanTyping.',
|
|
56
|
+
required: true
|
|
57
|
+
},
|
|
58
|
+
instructions: {
|
|
59
|
+
description: 'Specific behaviors, branches, errors, and edge cases that must be tested.',
|
|
60
|
+
required: false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
examples: [
|
|
64
|
+
'tests/unit/auth/LoginFlow.test.ts',
|
|
65
|
+
'tests/unit/browser/BrowserFactory.test.ts',
|
|
66
|
+
'tests/unit/core/ActorRunner.test.ts',
|
|
67
|
+
'tests/unit/interaction/HumanTyping.test.ts',
|
|
68
|
+
'tests/fixtures/FakePage.ts',
|
|
69
|
+
'tests/fixtures/FakeCursor.ts',
|
|
70
|
+
'tests/fixtures/makeContext.ts'
|
|
71
|
+
],
|
|
72
|
+
context: [
|
|
73
|
+
{ kind: 'path', path: 'vitest.config.ts', description: 'Vitest configuration.' },
|
|
74
|
+
{ kind: 'pattern', pattern: 'tests/unit/{{areaKebab}}/*.test.ts', description: 'Existing tests in the target area.', limit: 8 },
|
|
75
|
+
{ kind: 'pattern', pattern: 'tests/unit/**/*.test.ts', description: 'Representative test style from the rest of the repo.', limit: 5 },
|
|
76
|
+
{ kind: 'path', path: 'tests/fixtures/FakePage.ts', description: 'Main fake page fixture.' },
|
|
77
|
+
{ kind: 'path', path: 'tests/fixtures/FakeCursor.ts', description: 'Fake cursor fixture.' },
|
|
78
|
+
{ kind: 'path', path: 'tests/fixtures/FakeCredentialsProvider.ts', description: 'Fake credentials fixture.' },
|
|
79
|
+
{ kind: 'path', path: 'tests/fixtures/makeContext.ts', description: 'ActorContext test fixture.' },
|
|
80
|
+
{ kind: 'path', path: 'src/{{areaKebab}}/{{subjectPascal}}.ts', description: 'Conventional source module under test, when present.', required: false }
|
|
81
|
+
],
|
|
82
|
+
keywordContexts: [
|
|
83
|
+
{
|
|
84
|
+
keywords: ['login', 'auth', 'credentials', 'multi-step'],
|
|
85
|
+
context: [
|
|
86
|
+
{ kind: 'path', path: 'src/auth/LoginFlow.ts', description: 'Auth source likely under test.' },
|
|
87
|
+
{ kind: 'path', path: 'src/auth/LoginFlow.types.ts', description: 'Auth types likely under test.' }
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
keywords: ['browser', 'chrome', 'profile', 'remote debugging'],
|
|
92
|
+
context: [
|
|
93
|
+
{ kind: 'path', path: 'src/browser/BrowserFactory.ts', description: 'Browser source likely under test.' },
|
|
94
|
+
{ kind: 'path', path: 'src/browser/PuppeteerLike.ts', description: 'Fakeable browser/page interfaces.' }
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
keywords: ['interaction', 'typing', 'cursor', 'forms'],
|
|
99
|
+
context: [
|
|
100
|
+
{ kind: 'pattern', pattern: 'src/interaction/*.ts', description: 'Interaction source files.', limit: 10 }
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
tooling: {
|
|
105
|
+
allowGetExistingCode: true,
|
|
106
|
+
allowFindFiles: true,
|
|
107
|
+
allowSearchRepo: true
|
|
108
|
+
}
|
|
109
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const workflow = {
|
|
2
|
+
"description": "Describe what this workflow orchestrates.",
|
|
3
|
+
"parameters": {
|
|
4
|
+
"instructions": {
|
|
5
|
+
"description": "User-provided instructions passed to the workflow steps.",
|
|
6
|
+
"required": true
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"steps": [
|
|
10
|
+
{
|
|
11
|
+
"generationId": "abstract",
|
|
12
|
+
"description": "Run one generation step with interpolated instructions.",
|
|
13
|
+
"params": {
|
|
14
|
+
"instructions": "{{instructions}}"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default workflow;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const starter = {
|
|
2
|
+
"description": "A minimal starter workflow that forwards instructions to the abstract generator.",
|
|
3
|
+
"parameters": {
|
|
4
|
+
"instructions": {
|
|
5
|
+
"description": "Guidance for what to generate.",
|
|
6
|
+
"required": true
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"steps": [
|
|
10
|
+
{
|
|
11
|
+
"generationId": "abstract",
|
|
12
|
+
"description": "Run abstract generation with workflow-provided instructions.",
|
|
13
|
+
"params": {
|
|
14
|
+
"instructions": "{{instructions}}"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default starter;
|
package/ai-gen.config.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export const config = {
|
|
2
|
+
"repoRoot": ".",
|
|
3
|
+
"generationsDir": ".ai/generators",
|
|
4
|
+
"workflowsDir": ".ai/workflows",
|
|
5
|
+
"model": "gpt-5.3-codex",
|
|
6
|
+
"maxToolRounds": 100,
|
|
7
|
+
"maxContextFileSizeBytes": 60000,
|
|
8
|
+
"defaultMaxOutputFiles": 10,
|
|
9
|
+
"ignore": [
|
|
10
|
+
".git",
|
|
11
|
+
"node_modules",
|
|
12
|
+
"dist",
|
|
13
|
+
"build",
|
|
14
|
+
".next",
|
|
15
|
+
".turbo",
|
|
16
|
+
".cache",
|
|
17
|
+
"coverage",
|
|
18
|
+
".idea",
|
|
19
|
+
".vscode",
|
|
20
|
+
".langgraph_api",
|
|
21
|
+
".langgraph_checkpoint",
|
|
22
|
+
".easigen",
|
|
23
|
+
"dist",
|
|
24
|
+
|
|
25
|
+
"package-lock.json",
|
|
26
|
+
],
|
|
27
|
+
"offLimits": [
|
|
28
|
+
".env",
|
|
29
|
+
".env.*",
|
|
30
|
+
"*.pem",
|
|
31
|
+
"*.key",
|
|
32
|
+
"*.crt",
|
|
33
|
+
"*.p12",
|
|
34
|
+
"*.pfx",
|
|
35
|
+
".easigen",
|
|
36
|
+
"dist",
|
|
37
|
+
".git",
|
|
38
|
+
|
|
39
|
+
"node_modules",
|
|
40
|
+
"dist",
|
|
41
|
+
"build",
|
|
42
|
+
".next",
|
|
43
|
+
".turbo",
|
|
44
|
+
".cache",
|
|
45
|
+
"coverage",
|
|
46
|
+
".idea",
|
|
47
|
+
".vscode",
|
|
48
|
+
".langgraph_api",
|
|
49
|
+
".langgraph_checkpoint",
|
|
50
|
+
".easigen",
|
|
51
|
+
"dist",
|
|
52
|
+
|
|
53
|
+
"package-lock.json",
|
|
54
|
+
],
|
|
55
|
+
"defaultContext": [],
|
|
56
|
+
"defaultKeywordContexts": [],
|
|
57
|
+
"openai": {
|
|
58
|
+
"timeoutMs": 120000,
|
|
59
|
+
"reconnectPollTimeoutMs": 30000,
|
|
60
|
+
"reconnectPollIntervalMs": 2000
|
|
61
|
+
},
|
|
62
|
+
"logging": {
|
|
63
|
+
"level": "info",
|
|
64
|
+
"pretty": true
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export default config;
|
package/package.json
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epsilon-asi/actors",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "A TypeScript Puppeteer actor framework using existing Chrome profiles and ghost-cursor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"mainDir": "./",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": {
|
|
11
10
|
"types": "./dist/index.d.ts",
|
|
12
11
|
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
"./package.json": "./package.json"
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
17
14
|
},
|
|
18
15
|
"bin": {
|
|
19
16
|
"paf": "./dist/cli/run.js"
|
|
20
17
|
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"README.md",
|
|
24
|
-
"LICENSE"
|
|
25
|
-
],
|
|
26
18
|
"scripts": {
|
|
27
19
|
"build": "tsc -p tsconfig.build.json",
|
|
28
20
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
@@ -38,7 +30,7 @@
|
|
|
38
30
|
"devDependencies": {
|
|
39
31
|
"@types/node": "^24.10.1",
|
|
40
32
|
"@vitest/coverage-v8": "^4.1.7",
|
|
41
|
-
|
|
33
|
+
|
|
42
34
|
"vitest": "^4.1.7"
|
|
43
35
|
},
|
|
44
36
|
"engines": {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ActorContext } from '../core/ActorContext.js';
|
|
2
|
+
import type { LoginFlowDefinition } from './LoginFlow.types.js';
|
|
3
|
+
|
|
4
|
+
export class AuthStateDetector {
|
|
5
|
+
async isLoggedIn(context: ActorContext, definition: LoginFlowDefinition): Promise<boolean> {
|
|
6
|
+
if (definition.behavior?.authCheckUrl !== undefined) {
|
|
7
|
+
await context.nav.goto(definition.behavior.authCheckUrl);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (definition.hooks?.verifyLoggedIn !== undefined) {
|
|
11
|
+
return Boolean(await definition.hooks.verifyLoggedIn(context));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return context.page.exists(definition.selectors.loggedInSignal, {
|
|
15
|
+
timeout: definition.behavior?.loggedInTimeoutMs ?? 2_000
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AuthError } from '../errors/AuthError.js';
|
|
2
|
+
|
|
3
|
+
export interface Credentials {
|
|
4
|
+
username: string;
|
|
5
|
+
password: string;
|
|
6
|
+
accountId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CredentialRef {
|
|
10
|
+
id: string;
|
|
11
|
+
usernameEnv?: string;
|
|
12
|
+
passwordEnv?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CredentialsProvider {
|
|
16
|
+
getCredentials(ref: CredentialRef): Promise<Credentials>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class EnvCredentialsProvider implements CredentialsProvider {
|
|
20
|
+
async getCredentials(ref: CredentialRef): Promise<Credentials> {
|
|
21
|
+
const usernameKey = ref.usernameEnv ?? `${ref.id.toUpperCase()}_USERNAME`;
|
|
22
|
+
const passwordKey = ref.passwordEnv ?? `${ref.id.toUpperCase()}_PASSWORD`;
|
|
23
|
+
const username = process.env[usernameKey];
|
|
24
|
+
const password = process.env[passwordKey];
|
|
25
|
+
|
|
26
|
+
if (username === undefined || username.length === 0) {
|
|
27
|
+
throw new AuthError(`Missing username environment variable: ${usernameKey}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (password === undefined || password.length === 0) {
|
|
31
|
+
throw new AuthError(`Missing password environment variable: ${passwordKey}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return { username, password, accountId: ref.id };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class StaticCredentialsProvider implements CredentialsProvider {
|
|
39
|
+
constructor(private readonly credentials: Record<string, Credentials>) {}
|
|
40
|
+
|
|
41
|
+
async getCredentials(ref: CredentialRef): Promise<Credentials> {
|
|
42
|
+
const credential = this.credentials[ref.id];
|
|
43
|
+
if (credential === undefined) {
|
|
44
|
+
throw new AuthError(`No static credentials registered for credential id: ${ref.id}`);
|
|
45
|
+
}
|
|
46
|
+
return credential;
|
|
47
|
+
}
|
|
48
|
+
}
|