axgram 0.1.0
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/README.md +126 -0
- package/dist/bin/axgram-hook.js +77 -0
- package/dist/bin/axgram-hook.js.map +1 -0
- package/dist/bin/axgram.js +386 -0
- package/dist/bin/axgram.js.map +1 -0
- package/dist/commands/hook-session-start.js +85 -0
- package/dist/commands/hook-session-start.js.map +1 -0
- package/dist/commands/hook-stop.js +73 -0
- package/dist/commands/hook-stop.js.map +1 -0
- package/dist/commands/import.js +56 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/invitations.js +153 -0
- package/dist/commands/invitations.js.map +1 -0
- package/dist/commands/login.js +125 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +11 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/members.js +231 -0
- package/dist/commands/members.js.map +1 -0
- package/dist/commands/mine.js +78 -0
- package/dist/commands/mine.js.map +1 -0
- package/dist/commands/orgs.js +153 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/projects.js +285 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/teams.js +153 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/auth.js +128 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/chunkers/exchange-pair.js +51 -0
- package/dist/lib/chunkers/exchange-pair.js.map +1 -0
- package/dist/lib/chunkers/index.js +74 -0
- package/dist/lib/chunkers/index.js.map +1 -0
- package/dist/lib/chunkers/line-group.js +20 -0
- package/dist/lib/chunkers/line-group.js.map +1 -0
- package/dist/lib/chunkers/paragraph.js +29 -0
- package/dist/lib/chunkers/paragraph.js.map +1 -0
- package/dist/lib/chunkers/types.js +3 -0
- package/dist/lib/chunkers/types.js.map +1 -0
- package/dist/lib/config-dir.js +30 -0
- package/dist/lib/config-dir.js.map +1 -0
- package/dist/lib/destructive-confirm.js +71 -0
- package/dist/lib/destructive-confirm.js.map +1 -0
- package/dist/lib/entity-extractor.js +182 -0
- package/dist/lib/entity-extractor.js.map +1 -0
- package/dist/lib/global-config.js +42 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/hook-settings.js +87 -0
- package/dist/lib/hook-settings.js.map +1 -0
- package/dist/lib/hook-state.js +38 -0
- package/dist/lib/hook-state.js.map +1 -0
- package/dist/lib/importers/chatgpt.js +89 -0
- package/dist/lib/importers/chatgpt.js.map +1 -0
- package/dist/lib/importers/claude.js +47 -0
- package/dist/lib/importers/claude.js.map +1 -0
- package/dist/lib/importers/gemini.js +38 -0
- package/dist/lib/importers/gemini.js.map +1 -0
- package/dist/lib/importers/markdown.js +47 -0
- package/dist/lib/importers/markdown.js.map +1 -0
- package/dist/lib/importers/obsidian.js +62 -0
- package/dist/lib/importers/obsidian.js.map +1 -0
- package/dist/lib/importers/run.js +51 -0
- package/dist/lib/importers/run.js.map +1 -0
- package/dist/lib/ingest.js +101 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/mcp-client.js +56 -0
- package/dist/lib/mcp-client.js.map +1 -0
- package/dist/lib/project-resolver.js +42 -0
- package/dist/lib/project-resolver.js.map +1 -0
- package/dist/lib/remote-url.js +23 -0
- package/dist/lib/remote-url.js.map +1 -0
- package/dist/lib/repo-bindings.js +52 -0
- package/dist/lib/repo-bindings.js.map +1 -0
- package/dist/lib/repo.js +72 -0
- package/dist/lib/repo.js.map +1 -0
- package/dist/lib/room-detector.js +99 -0
- package/dist/lib/room-detector.js.map +1 -0
- package/dist/lib/slugify.js +17 -0
- package/dist/lib/slugify.js.map +1 -0
- package/dist/lib/supabase-client.js +35 -0
- package/dist/lib/supabase-client.js.map +1 -0
- package/dist/lib/tool-vocab.js +114 -0
- package/dist/lib/tool-vocab.js.map +1 -0
- package/dist/lib/transcript.js +68 -0
- package/dist/lib/transcript.js.map +1 -0
- package/dist/lib/walker.js +81 -0
- package/dist/lib/walker.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hookSessionStartCommand = hookSessionStartCommand;
|
|
4
|
+
const project_resolver_1 = require("../lib/project-resolver");
|
|
5
|
+
const supabase_client_1 = require("../lib/supabase-client");
|
|
6
|
+
/**
|
|
7
|
+
* Session-start hook. Emits an addendum on stdout that Claude Code injects
|
|
8
|
+
* into the session's system prompt. Three branches:
|
|
9
|
+
*
|
|
10
|
+
* 1. Resolved project (flag/env/binding/global): one-paragraph briefing
|
|
11
|
+
* naming the project and a one-line nudge to use Axgram's memory
|
|
12
|
+
* tools.
|
|
13
|
+
* 2. Unresolved but inside a git repo: ask the user to link this repo
|
|
14
|
+
* or create a new project, with concrete CLI suggestions.
|
|
15
|
+
* 3. Unresolved and not in a git repo: softer briefing — remind the
|
|
16
|
+
* user that AXGRAM_PROJECT_ID overrides the binding.
|
|
17
|
+
*
|
|
18
|
+
* Always exits 0 — never blocks the session.
|
|
19
|
+
*/
|
|
20
|
+
async function hookSessionStartCommand(opts = {}, deps = {}) {
|
|
21
|
+
const log = deps.log ?? ((m) => process.stdout.write(`${m}\n`));
|
|
22
|
+
const errOut = deps.err ?? ((m) => process.stderr.write(`${m}\n`));
|
|
23
|
+
// Plan 5 Task 12: surface pending invitations to stderr. Best-effort —
|
|
24
|
+
// any failure (no creds, network glitch, RLS hiccup) is swallowed.
|
|
25
|
+
await surfacePendingInvitations(errOut, deps);
|
|
26
|
+
const resolved = await (0, project_resolver_1.resolveActiveProject)({
|
|
27
|
+
flag: opts.project,
|
|
28
|
+
...(opts.cwd ? { cwd: opts.cwd } : {}),
|
|
29
|
+
});
|
|
30
|
+
if (resolved.projectId) {
|
|
31
|
+
log([
|
|
32
|
+
`<axgram>`,
|
|
33
|
+
`You are working in Axgram project ${resolved.projectId} (resolved via ${resolved.source}).`,
|
|
34
|
+
`When this session ends, call axgram_diary_write + axgram_memories_filed_away to checkpoint memories.`,
|
|
35
|
+
`Use axgram_search and axgram_context to recall prior work in this project before answering.`,
|
|
36
|
+
`</axgram>`,
|
|
37
|
+
].join("\n"));
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
if (resolved.repoKey) {
|
|
41
|
+
log([
|
|
42
|
+
`<axgram>`,
|
|
43
|
+
`This repository (${resolved.repoKey}) isn't linked to an Axgram project. Before continuing,`,
|
|
44
|
+
`please ask the user one of:`,
|
|
45
|
+
` - "Should I link this repo to an existing Axgram project? (axgram projects link <id>)"`,
|
|
46
|
+
` - "Should I create a new project for this repo? (axgram projects create <name> && axgram projects link <id>)"`,
|
|
47
|
+
`Run \`axgram projects ls\` to enumerate the user's accessible projects.`,
|
|
48
|
+
`</axgram>`,
|
|
49
|
+
].join("\n"));
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
log([
|
|
53
|
+
`<axgram>`,
|
|
54
|
+
`No Axgram project is bound to this shell. If memory recall matters for this task, ask`,
|
|
55
|
+
`the user which project applies — or set AXGRAM_PROJECT_ID=<id> in the environment.`,
|
|
56
|
+
`Run \`axgram projects ls\` for the available list.`,
|
|
57
|
+
`</axgram>`,
|
|
58
|
+
].join("\n"));
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
async function surfacePendingInvitations(errOut, deps) {
|
|
62
|
+
try {
|
|
63
|
+
const count = deps.pendingInvitationsCount
|
|
64
|
+
? await deps.pendingInvitationsCount()
|
|
65
|
+
: await defaultPendingInvitationsCount();
|
|
66
|
+
if (count > 0) {
|
|
67
|
+
errOut(`You have ${count} pending invitation${count === 1 ? "" : "s"}. ` +
|
|
68
|
+
`Run \`axgram invitations ls\` to inspect, or \`axgram invitations accept <token>\` to join.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Never block the session — swallow any error.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function defaultPendingInvitationsCount() {
|
|
76
|
+
const s = await (0, supabase_client_1.authenticatedSupabase)();
|
|
77
|
+
const { count, error } = await s
|
|
78
|
+
.from("invitations")
|
|
79
|
+
.select("id", { count: "exact", head: true })
|
|
80
|
+
.is("accepted_at", null);
|
|
81
|
+
if (error)
|
|
82
|
+
return 0;
|
|
83
|
+
return count ?? 0;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=hook-session-start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-session-start.js","sourceRoot":"","sources":["../../src/commands/hook-session-start.ts"],"names":[],"mappings":";;AA+BA,0DAsDC;AArFD,8DAA+D;AAC/D,4DAA+D;AAgB/D;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,uBAAuB,CAC3C,OAAgC,EAAE,EAClC,OAA6B,EAAE;IAE/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAE3E,uEAAuE;IACvE,mEAAmE;IACnE,MAAM,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,MAAM,IAAA,uCAAoB,EAAC;QAC1C,IAAI,EAAE,IAAI,CAAC,OAAO;QAClB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvC,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,GAAG,CACD;YACE,UAAU;YACV,qCAAqC,QAAQ,CAAC,SAAS,kBAAkB,QAAQ,CAAC,MAAM,IAAI;YAC5F,sGAAsG;YACtG,6FAA6F;YAC7F,WAAW;SACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,GAAG,CACD;YACE,UAAU;YACV,oBAAoB,QAAQ,CAAC,OAAO,yDAAyD;YAC7F,6BAA6B;YAC7B,0FAA0F;YAC1F,iHAAiH;YACjH,yEAAyE;YACzE,WAAW;SACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,GAAG,CACD;QACE,UAAU;QACV,uFAAuF;QACvF,oFAAoF;QACpF,oDAAoD;QACpD,WAAW;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,MAA2B,EAC3B,IAA0B;IAE1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB;YACxC,CAAC,CAAC,MAAM,IAAI,CAAC,uBAAuB,EAAE;YACtC,CAAC,CAAC,MAAM,8BAA8B,EAAE,CAAC;QAC3C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,CACJ,YAAY,KAAK,sBAAsB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;gBAC/D,6FAA6F,CAChG,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,8BAA8B;IAC3C,MAAM,CAAC,GAAG,MAAM,IAAA,uCAAqB,GAAE,CAAC;IACxC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;SAC7B,IAAI,CAAC,aAAa,CAAC;SACnB,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;SAC5C,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAC3B,IAAI,KAAK;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,KAAK,IAAI,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hookStopCommand = hookStopCommand;
|
|
4
|
+
const hook_settings_1 = require("../lib/hook-settings");
|
|
5
|
+
const hook_state_1 = require("../lib/hook-state");
|
|
6
|
+
const project_resolver_1 = require("../lib/project-resolver");
|
|
7
|
+
const transcript_1 = require("../lib/transcript");
|
|
8
|
+
/**
|
|
9
|
+
* Stop hook handler. Returns the exit code:
|
|
10
|
+
* 0 — quiet pass (counter under threshold, or no project resolved).
|
|
11
|
+
* 2 — block + emit stderr prompt instructing the model to file memories.
|
|
12
|
+
*
|
|
13
|
+
* Per Claude Code's hook protocol, exit 2 surfaces stderr to the model;
|
|
14
|
+
* exit 0 lets the session terminate normally.
|
|
15
|
+
*/
|
|
16
|
+
async function hookStopCommand(opts, deps = {}) {
|
|
17
|
+
const errOut = deps.err ?? ((m) => process.stderr.write(`${m}\n`));
|
|
18
|
+
// Resolve project. If unresolved, exit 0 silently — SessionStart handles
|
|
19
|
+
// disambiguation; we don't want to disrupt a misconfigured session.
|
|
20
|
+
const resolved = await (0, project_resolver_1.resolveActiveProject)({ flag: opts.project });
|
|
21
|
+
if (!resolved.projectId)
|
|
22
|
+
return 0;
|
|
23
|
+
const projectId = resolved.projectId;
|
|
24
|
+
let stats;
|
|
25
|
+
try {
|
|
26
|
+
stats = await (0, transcript_1.readTranscript)(opts.transcript);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
errOut(`axgram-hook: could not read transcript: ${e.message}`);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
let threshold;
|
|
33
|
+
let enabled = true;
|
|
34
|
+
if (opts.threshold !== undefined) {
|
|
35
|
+
threshold = opts.threshold;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const settings = await (0, hook_settings_1.getEffectiveHookSettings)(projectId, {
|
|
39
|
+
err: errOut,
|
|
40
|
+
...(opts.workerUrl !== undefined ? { workerUrl: opts.workerUrl } : {}),
|
|
41
|
+
...(deps.mcpClientFactory
|
|
42
|
+
? { mcpClientFactory: deps.mcpClientFactory }
|
|
43
|
+
: {}),
|
|
44
|
+
});
|
|
45
|
+
threshold = settings.threshold;
|
|
46
|
+
enabled = settings.enabled;
|
|
47
|
+
}
|
|
48
|
+
// User-disabled hook → still update the counter so the SessionStart side
|
|
49
|
+
// sees it, but never block.
|
|
50
|
+
if (!enabled) {
|
|
51
|
+
const disabledState = await (0, hook_state_1.loadHookState)(projectId);
|
|
52
|
+
disabledState.exchanges_since_checkpoint = stats.exchangesSinceCheckpoint;
|
|
53
|
+
await (0, hook_state_1.saveHookState)(projectId, disabledState);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
const state = await (0, hook_state_1.loadHookState)(projectId);
|
|
57
|
+
state.exchanges_since_checkpoint = stats.exchangesSinceCheckpoint;
|
|
58
|
+
if (stats.filedAtLeastOnce) {
|
|
59
|
+
state.last_checkpoint_at = new Date().toISOString();
|
|
60
|
+
}
|
|
61
|
+
await (0, hook_state_1.saveHookState)(projectId, state);
|
|
62
|
+
if (stats.exchangesSinceCheckpoint < threshold)
|
|
63
|
+
return 0;
|
|
64
|
+
errOut([
|
|
65
|
+
`Axgram: ${stats.exchangesSinceCheckpoint} user exchanges since the last memory checkpoint (threshold ${threshold}).`,
|
|
66
|
+
"Before this session terminates, please:",
|
|
67
|
+
" 1. Call axgram_diary_write with a short AAAK-format summary of what we did.",
|
|
68
|
+
" 2. Call axgram_add_drawer (or axgram_bulk_add) for any decisions/conclusions worth retaining.",
|
|
69
|
+
" 3. Call axgram_memories_filed_away to acknowledge the checkpoint.",
|
|
70
|
+
].join("\n"));
|
|
71
|
+
return 2;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=hook-stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-stop.js","sourceRoot":"","sources":["../../src/commands/hook-stop.ts"],"names":[],"mappings":";;AAmCA,0CAgEC;AAnGD,wDAG8B;AAC9B,kDAAiE;AACjE,8DAA+D;AAC/D,kDAAmD;AAqBnD;;;;;;;GAOG;AACI,KAAK,UAAU,eAAe,CACnC,IAAqB,EACrB,OAAqB,EAAE;IAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAE3E,yEAAyE;IACzE,oEAAoE;IACpE,MAAM,QAAQ,GAAG,MAAM,IAAA,uCAAoB,EAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,OAAO,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;IAErC,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,IAAA,2BAAc,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,2CAA4C,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,SAAiB,CAAC;IACtB,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,MAAM,IAAA,wCAAwB,EAAC,SAAS,EAAE;YACzD,GAAG,EAAE,MAAM;YACX,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,gBAAgB;gBACvB,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE;gBAC7C,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC/B,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,yEAAyE;IACzE,4BAA4B;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,aAAa,GAAG,MAAM,IAAA,0BAAa,EAAC,SAAS,CAAC,CAAC;QACrD,aAAa,CAAC,0BAA0B,GAAG,KAAK,CAAC,wBAAwB,CAAC;QAC1E,MAAM,IAAA,0BAAa,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAC9C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,IAAA,0BAAa,EAAC,SAAS,CAAC,CAAC;IAC7C,KAAK,CAAC,0BAA0B,GAAG,KAAK,CAAC,wBAAwB,CAAC;IAClE,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,KAAK,CAAC,kBAAkB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,IAAA,0BAAa,EAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEtC,IAAI,KAAK,CAAC,wBAAwB,GAAG,SAAS;QAAE,OAAO,CAAC,CAAC;IAEzD,MAAM,CACJ;QACE,WAAW,KAAK,CAAC,wBAAwB,+DAA+D,SAAS,IAAI;QACrH,yCAAyC;QACzC,+EAA+E;QAC/E,iGAAiG;QACjG,qEAAqE;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.importChatGpt = importChatGpt;
|
|
4
|
+
exports.importClaude = importClaude;
|
|
5
|
+
exports.importGemini = importGemini;
|
|
6
|
+
exports.importObsidian = importObsidian;
|
|
7
|
+
exports.importMarkdown = importMarkdown;
|
|
8
|
+
const chatgpt_1 = require("../lib/importers/chatgpt");
|
|
9
|
+
const claude_1 = require("../lib/importers/claude");
|
|
10
|
+
const gemini_1 = require("../lib/importers/gemini");
|
|
11
|
+
const markdown_1 = require("../lib/importers/markdown");
|
|
12
|
+
const obsidian_1 = require("../lib/importers/obsidian");
|
|
13
|
+
const run_1 = require("../lib/importers/run");
|
|
14
|
+
function shellOpts(label, opts) {
|
|
15
|
+
return {
|
|
16
|
+
label,
|
|
17
|
+
...(opts.project !== undefined ? { project: opts.project } : {}),
|
|
18
|
+
...(opts.workerUrl !== undefined ? { workerUrl: opts.workerUrl } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async function importChatGpt(filePath, opts = {}, deps = {}) {
|
|
22
|
+
return (0, run_1.runImporter)(() => (0, chatgpt_1.parseChatGptExport)(filePath, {
|
|
23
|
+
...(opts.wing !== undefined ? { wing: opts.wing } : {}),
|
|
24
|
+
...(opts.room !== undefined ? { room: opts.room } : {}),
|
|
25
|
+
...(opts.noKg !== undefined ? { noKg: opts.noKg } : {}),
|
|
26
|
+
}), shellOpts("ChatGPT export", opts), deps);
|
|
27
|
+
}
|
|
28
|
+
async function importClaude(filePath, opts = {}, deps = {}) {
|
|
29
|
+
return (0, run_1.runImporter)(() => (0, claude_1.parseClaudeExport)(filePath, {
|
|
30
|
+
...(opts.wing !== undefined ? { wing: opts.wing } : {}),
|
|
31
|
+
...(opts.room !== undefined ? { room: opts.room } : {}),
|
|
32
|
+
...(opts.noKg !== undefined ? { noKg: opts.noKg } : {}),
|
|
33
|
+
}), shellOpts("Claude.ai export", opts), deps);
|
|
34
|
+
}
|
|
35
|
+
async function importGemini(filePath, opts = {}, deps = {}) {
|
|
36
|
+
return (0, run_1.runImporter)(() => (0, gemini_1.parseGeminiExport)(filePath, {
|
|
37
|
+
...(opts.wing !== undefined ? { wing: opts.wing } : {}),
|
|
38
|
+
...(opts.room !== undefined ? { room: opts.room } : {}),
|
|
39
|
+
...(opts.noKg !== undefined ? { noKg: opts.noKg } : {}),
|
|
40
|
+
}), shellOpts("Gemini Takeout", opts), deps);
|
|
41
|
+
}
|
|
42
|
+
async function importObsidian(vaultPath, opts = {}, deps = {}) {
|
|
43
|
+
return (0, run_1.runImporter)(() => (0, obsidian_1.parseObsidianVault)(vaultPath, {
|
|
44
|
+
...(opts.wing !== undefined ? { wing: opts.wing } : {}),
|
|
45
|
+
...(opts.room !== undefined ? { room: opts.room } : {}),
|
|
46
|
+
...(opts.noKg !== undefined ? { noKg: opts.noKg } : {}),
|
|
47
|
+
}), shellOpts("Obsidian vault", opts), deps);
|
|
48
|
+
}
|
|
49
|
+
async function importMarkdown(rootPath, opts, deps = {}) {
|
|
50
|
+
return (0, run_1.runImporter)(() => (0, markdown_1.parseMarkdownDir)(rootPath, {
|
|
51
|
+
wing: opts.wing,
|
|
52
|
+
...(opts.room !== undefined ? { room: opts.room } : {}),
|
|
53
|
+
...(opts.noKg !== undefined ? { noKg: opts.noKg } : {}),
|
|
54
|
+
}), shellOpts("markdown directory", opts), deps);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":";;AA8BA,sCAeC;AAED,oCAeC;AAED,oCAeC;AAED,wCAeC;AAED,wCAeC;AAjHD,sDAA8D;AAC9D,oDAA4D;AAC5D,oDAA4D;AAC5D,wDAA6D;AAC7D,wDAA+D;AAC/D,8CAI8B;AAU9B,SAAS,SAAS,CAChB,KAAa,EACb,IAAsB;IAEtB,OAAO;QACL,KAAK;QACL,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,OAAyB,EAAE,EAC3B,OAAwB,EAAE;IAE1B,OAAO,IAAA,iBAAW,EAChB,GAAG,EAAE,CACH,IAAA,4BAAkB,EAAC,QAAQ,EAAE;QAC3B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,EACJ,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,EACjC,IAAI,CACL,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,OAAyB,EAAE,EAC3B,OAAwB,EAAE;IAE1B,OAAO,IAAA,iBAAW,EAChB,GAAG,EAAE,CACH,IAAA,0BAAiB,EAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,EACJ,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,EACnC,IAAI,CACL,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,OAAyB,EAAE,EAC3B,OAAwB,EAAE;IAE1B,OAAO,IAAA,iBAAW,EAChB,GAAG,EAAE,CACH,IAAA,0BAAiB,EAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,EACJ,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,EACjC,IAAI,CACL,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,cAAc,CAClC,SAAiB,EACjB,OAAyB,EAAE,EAC3B,OAAwB,EAAE;IAE1B,OAAO,IAAA,iBAAW,EAChB,GAAG,EAAE,CACH,IAAA,6BAAkB,EAAC,SAAS,EAAE;QAC5B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,EACJ,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,EACjC,IAAI,CACL,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,IAAyC,EACzC,OAAwB,EAAE;IAE1B,OAAO,IAAA,iBAAW,EAChB,GAAG,EAAE,CACH,IAAA,2BAAgB,EAAC,QAAQ,EAAE;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,EACJ,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,EACrC,IAAI,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Plan 5 Task 11: `axgram invitations` subcommands.
|
|
3
|
+
//
|
|
4
|
+
// ls, invite, revoke, accept, resend. The invite flow prints the
|
|
5
|
+
// accept_url to stdout for the inviter to share manually until Plan 7
|
|
6
|
+
// wires email delivery. Tokens are never written to log files.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.invitationsLs = invitationsLs;
|
|
9
|
+
exports.invitationsInvite = invitationsInvite;
|
|
10
|
+
exports.invitationsRevoke = invitationsRevoke;
|
|
11
|
+
exports.invitationsAccept = invitationsAccept;
|
|
12
|
+
exports.invitationsResend = invitationsResend;
|
|
13
|
+
const supabase_client_1 = require("../lib/supabase-client");
|
|
14
|
+
const defaultLog = (m) => process.stdout.write(`${m}\n`);
|
|
15
|
+
const defaultErr = (m) => process.stderr.write(`${m}\n`);
|
|
16
|
+
const isUuid = (s) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
|
|
17
|
+
async function buildSupabase(deps) {
|
|
18
|
+
return deps.supabaseFactory ? deps.supabaseFactory() : (0, supabase_client_1.authenticatedSupabase)();
|
|
19
|
+
}
|
|
20
|
+
async function resolveTeamId(s, idOrName) {
|
|
21
|
+
const q = s.from("teams").select("id");
|
|
22
|
+
const { data } = isUuid(idOrName)
|
|
23
|
+
? await q.eq("id", idOrName).maybeSingle()
|
|
24
|
+
: await q.eq("name", idOrName).maybeSingle();
|
|
25
|
+
return data?.id ?? null;
|
|
26
|
+
}
|
|
27
|
+
function buildAcceptUrl(token, base) {
|
|
28
|
+
const root = (base ?? process.env.AXGRAM_APP_BASE_URL ?? "http://localhost:3000").replace(/\/+$/, "");
|
|
29
|
+
return `${root}/invitations/accept?token=${encodeURIComponent(token)}`;
|
|
30
|
+
}
|
|
31
|
+
async function invitationsLs(teamFlag, deps = {}) {
|
|
32
|
+
const log = deps.log ?? defaultLog;
|
|
33
|
+
const errOut = deps.err ?? defaultErr;
|
|
34
|
+
const s = await buildSupabase(deps);
|
|
35
|
+
let q = s
|
|
36
|
+
.from("invitations")
|
|
37
|
+
.select("id, team_id, email, role, expires_at, accepted_at, created_at")
|
|
38
|
+
.order("created_at", { ascending: false });
|
|
39
|
+
if (teamFlag) {
|
|
40
|
+
const tid = await resolveTeamId(s, teamFlag);
|
|
41
|
+
if (!tid) {
|
|
42
|
+
errOut(`No team found matching "${teamFlag}".`);
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
q = q.eq("team_id", tid);
|
|
46
|
+
}
|
|
47
|
+
const { data, error } = await q;
|
|
48
|
+
if (error) {
|
|
49
|
+
errOut(`Failed to list invitations: ${error.message}`);
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
if (!data || data.length === 0) {
|
|
53
|
+
log("No invitations.");
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
for (const i of data) {
|
|
57
|
+
const status = i.accepted_at ? "accepted" : new Date(i.expires_at).getTime() < Date.now() ? "expired" : "pending";
|
|
58
|
+
log(`${i.id} [${status}] ${i.email} role=${i.role} team=${i.team_id}`);
|
|
59
|
+
}
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
async function invitationsInvite(email, options, deps = {}) {
|
|
63
|
+
const log = deps.log ?? defaultLog;
|
|
64
|
+
const errOut = deps.err ?? defaultErr;
|
|
65
|
+
const s = await buildSupabase(deps);
|
|
66
|
+
if (!options.team) {
|
|
67
|
+
errOut("--team <id-or-name> is required.");
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
const tid = await resolveTeamId(s, options.team);
|
|
71
|
+
if (!tid) {
|
|
72
|
+
errOut(`No team found matching "${options.team}".`);
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
// Look up org_id + invited_by.
|
|
76
|
+
const { data: team } = await s.from("teams").select("org_id").eq("id", tid).single();
|
|
77
|
+
const { data: who } = await s.auth.getUser();
|
|
78
|
+
if (!who.user) {
|
|
79
|
+
errOut("Not logged in. Run `axgram login`.");
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
const { data, error } = await s
|
|
83
|
+
.from("invitations")
|
|
84
|
+
.insert({
|
|
85
|
+
org_id: team.org_id,
|
|
86
|
+
team_id: tid,
|
|
87
|
+
email,
|
|
88
|
+
role: options.role ?? "member",
|
|
89
|
+
invited_by: who.user.id,
|
|
90
|
+
})
|
|
91
|
+
.select("id, token, expires_at")
|
|
92
|
+
.single();
|
|
93
|
+
if (error) {
|
|
94
|
+
if (error.code === "23505") {
|
|
95
|
+
errOut(`A pending invitation for ${email} already exists. Use \`axgram invitations resend <id>\`.`);
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
errOut(`Failed to invite: ${error.message}`);
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
const acceptUrl = buildAcceptUrl(data.token, deps.appBaseUrl);
|
|
102
|
+
log(`Invited ${email}. Share this link out-of-band:`);
|
|
103
|
+
log("");
|
|
104
|
+
log(acceptUrl);
|
|
105
|
+
log("");
|
|
106
|
+
log(`(Expires at ${data.expires_at}; resend to extend.)`);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
async function invitationsRevoke(invitationId, deps = {}) {
|
|
110
|
+
const log = deps.log ?? defaultLog;
|
|
111
|
+
const errOut = deps.err ?? defaultErr;
|
|
112
|
+
const s = await buildSupabase(deps);
|
|
113
|
+
const { error } = await s.from("invitations").delete().eq("id", invitationId);
|
|
114
|
+
if (error) {
|
|
115
|
+
errOut(`Failed to revoke invitation: ${error.message}`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
log(`Revoked invitation ${invitationId}.`);
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
async function invitationsAccept(token, deps = {}) {
|
|
122
|
+
const log = deps.log ?? defaultLog;
|
|
123
|
+
const errOut = deps.err ?? defaultErr;
|
|
124
|
+
const s = await buildSupabase(deps);
|
|
125
|
+
const { data, error } = await s.rpc("accept_invitation", { p_token: token });
|
|
126
|
+
if (error) {
|
|
127
|
+
if (error.code === "42501") {
|
|
128
|
+
errOut("This invitation was issued to a different email. Sign in as that user and retry.");
|
|
129
|
+
return 1;
|
|
130
|
+
}
|
|
131
|
+
errOut(`Failed to accept invitation: ${error.message}`);
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
const row = data[0];
|
|
135
|
+
log(`Joined team ${row.joined_team_id} as ${row.joined_role}.`);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
async function invitationsResend(invitationId, deps = {}) {
|
|
139
|
+
const log = deps.log ?? defaultLog;
|
|
140
|
+
const errOut = deps.err ?? defaultErr;
|
|
141
|
+
const s = await buildSupabase(deps);
|
|
142
|
+
const { data, error } = await s.rpc("resend_invitation", {
|
|
143
|
+
p_invitation_id: invitationId,
|
|
144
|
+
});
|
|
145
|
+
if (error) {
|
|
146
|
+
errOut(`Failed to resend invitation: ${error.message}`);
|
|
147
|
+
return 1;
|
|
148
|
+
}
|
|
149
|
+
const row = data[0];
|
|
150
|
+
log(`Extended invitation expiry to ${row.expires_at}.`);
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=invitations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invitations.js","sourceRoot":"","sources":["../../src/commands/invitations.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,EAAE;AACF,iEAAiE;AACjE,sEAAsE;AACtE,+DAA+D;;AAsC/D,sCAkCC;AAED,8CAkDC;AAED,8CAcC;AAED,8CAmBC;AAED,8CAiBC;AAjLD,4DAA+D;AAU/D,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjE,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAC3B,iEAAiE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE5E,KAAK,UAAU,aAAa,CAAC,IAA2B;IACtD,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,IAAA,uCAAqB,GAAE,CAAC;AACjF,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,CAAiB,EACjB,QAAgB;IAEhB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC/B,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE;QAC1C,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,OAAQ,IAAY,EAAE,EAAE,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,IAAa;IAClD,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtG,OAAO,GAAG,IAAI,6BAA6B,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;AACzE,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,QAA4B,EAC5B,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC,GAAG,CAAC;SACN,IAAI,CAAC,aAAa,CAAC;SACnB,MAAM,CAAC,+DAA+D,CAAC;SACvE,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,CAAC,2BAA2B,QAAQ,IAAI,CAAC,CAAC;YAChD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;IAChC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAa,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAClH,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,OAA+D,EAC/D,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,CAAC,kCAAkC,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,2BAA2B,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,+BAA+B;IAC/B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IACrF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,oCAAoC,CAAC,CAAC;QAC7C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;SAC5B,IAAI,CAAC,aAAa,CAAC;SACnB,MAAM,CAAC;QACN,MAAM,EAAG,IAAY,CAAC,MAAM;QAC5B,OAAO,EAAE,GAAG;QACZ,KAAK;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ;QAC9B,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;KACxB,CAAC;SACD,MAAM,CAAC,uBAAuB,CAAC;SAC/B,MAAM,EAAE,CAAC;IACZ,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,4BAA4B,KAAK,0DAA0D,CAAC,CAAC;YACpG,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,CAAC,qBAAqB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,SAAS,GAAG,cAAc,CAAE,IAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACvE,GAAG,CAAC,WAAW,KAAK,gCAAgC,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,SAAS,CAAC,CAAC;IACf,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,eAAgB,IAAY,CAAC,UAAU,sBAAsB,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,YAAoB,EACpB,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9E,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG,CAAC,sBAAsB,YAAY,GAAG,CAAC,CAAC;IAC3C,OAAO,CAAC,CAAC;AACX,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,kFAAkF,CAAC,CAAC;YAC3F,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAI,IAAc,CAAC,CAAC,CAAC,CAAC;IAC/B,GAAG,CAAC,eAAe,GAAG,CAAC,cAAc,OAAO,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC;IAChE,OAAO,CAAC,CAAC;AACX,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,YAAoB,EACpB,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,mBAAmB,EAAE;QACvD,eAAe,EAAE,YAAY;KAC9B,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAI,IAAc,CAAC,CAAC,CAAC,CAAC;IAC/B,GAAG,CAAC,iCAAiC,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startTokenReceiver = startTokenReceiver;
|
|
7
|
+
exports.loginCommand = loginCommand;
|
|
8
|
+
const node_http_1 = require("node:http");
|
|
9
|
+
const open_1 = __importDefault(require("open"));
|
|
10
|
+
const auth_1 = require("../lib/auth");
|
|
11
|
+
/**
|
|
12
|
+
* Spawns a tiny localhost HTTP server that listens for a single token POST
|
|
13
|
+
* from the worker-bridged login page. Returns the chosen port + a promise.
|
|
14
|
+
*
|
|
15
|
+
* Why localhost: browsers allow https→http requests to 127.0.0.1 from a
|
|
16
|
+
* secure context, so the worker-served page can POST tokens back here even
|
|
17
|
+
* though it's loaded over https. Same pattern as `gcloud auth login`.
|
|
18
|
+
*/
|
|
19
|
+
function startTokenReceiver(opts) {
|
|
20
|
+
const allowedOrigin = opts?.allowedOrigin ?? "*";
|
|
21
|
+
return new Promise((resolveOuter, rejectOuter) => {
|
|
22
|
+
let server;
|
|
23
|
+
const tokenPromise = new Promise((resolveToken, rejectToken) => {
|
|
24
|
+
server = (0, node_http_1.createServer)((req, res) => {
|
|
25
|
+
const corsHeaders = {
|
|
26
|
+
"Access-Control-Allow-Origin": allowedOrigin,
|
|
27
|
+
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
28
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
29
|
+
"Access-Control-Max-Age": "600",
|
|
30
|
+
};
|
|
31
|
+
if (req.method === "OPTIONS") {
|
|
32
|
+
res.writeHead(204, corsHeaders);
|
|
33
|
+
res.end();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (req.method !== "POST" || req.url !== "/token") {
|
|
37
|
+
res.writeHead(404, corsHeaders);
|
|
38
|
+
res.end();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const chunks = [];
|
|
42
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
43
|
+
req.on("end", () => {
|
|
44
|
+
try {
|
|
45
|
+
const body = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
46
|
+
if (typeof body.access_token !== "string" ||
|
|
47
|
+
typeof body.refresh_token !== "string" ||
|
|
48
|
+
typeof body.expires_at !== "number" ||
|
|
49
|
+
typeof body.supabase_url !== "string" ||
|
|
50
|
+
typeof body.supabase_anon_key !== "string") {
|
|
51
|
+
res.writeHead(400, {
|
|
52
|
+
...corsHeaders,
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
});
|
|
55
|
+
res.end(JSON.stringify({ error: "Invalid token payload" }));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
res.writeHead(200, {
|
|
59
|
+
...corsHeaders,
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
});
|
|
62
|
+
res.end(JSON.stringify({ ok: true }));
|
|
63
|
+
resolveToken(body);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
res.writeHead(400, {
|
|
67
|
+
...corsHeaders,
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
});
|
|
70
|
+
res.end(JSON.stringify({
|
|
71
|
+
error: `Invalid JSON: ${err.message}`,
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
req.on("error", rejectToken);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
server.on("error", (err) => {
|
|
79
|
+
rejectOuter(err);
|
|
80
|
+
});
|
|
81
|
+
// 0 = OS picks a free port.
|
|
82
|
+
server.listen(0, "127.0.0.1", () => {
|
|
83
|
+
const addr = server.address();
|
|
84
|
+
const port = addr.port;
|
|
85
|
+
resolveOuter({
|
|
86
|
+
port,
|
|
87
|
+
promise: tokenPromise,
|
|
88
|
+
close: () => new Promise((doneClose) => {
|
|
89
|
+
server.close(() => doneClose());
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Runs the full login flow: spawn local listener, open browser to the
|
|
97
|
+
* worker-bridged login page, wait for token POST, persist credentials.
|
|
98
|
+
*/
|
|
99
|
+
async function loginCommand(opts) {
|
|
100
|
+
const log = opts.log ?? ((m) => process.stdout.write(`${m}\n`));
|
|
101
|
+
const opener = opts.openImpl ?? ((url) => (0, open_1.default)(url));
|
|
102
|
+
const receiver = await startTokenReceiver();
|
|
103
|
+
const url = `${opts.workerUrl.replace(/\/+$/, "")}/cli-login?port=${receiver.port}`;
|
|
104
|
+
log(`Opening browser: ${url}`);
|
|
105
|
+
log("Complete sign-in in the browser; this terminal will resume automatically.");
|
|
106
|
+
try {
|
|
107
|
+
await opener(url);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
log(`Failed to open browser automatically: ${err.message}`);
|
|
111
|
+
log(`Open this URL manually: ${url}`);
|
|
112
|
+
}
|
|
113
|
+
const tokens = await receiver.promise;
|
|
114
|
+
await receiver.close();
|
|
115
|
+
const creds = {
|
|
116
|
+
access_token: tokens.access_token,
|
|
117
|
+
refresh_token: tokens.refresh_token,
|
|
118
|
+
expires_at: tokens.expires_at,
|
|
119
|
+
supabase_url: tokens.supabase_url,
|
|
120
|
+
supabase_anon_key: tokens.supabase_anon_key,
|
|
121
|
+
};
|
|
122
|
+
await (0, auth_1.saveCredentials)(creds);
|
|
123
|
+
log("Logged in.");
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logoutCommand = logoutCommand;
|
|
4
|
+
const auth_1 = require("../lib/auth");
|
|
5
|
+
async function logoutCommand(opts = {}) {
|
|
6
|
+
const log = opts.log ?? ((m) => process.stdout.write(`${m}\n`));
|
|
7
|
+
const had = await (0, auth_1.loadCredentials)();
|
|
8
|
+
await (0, auth_1.clearCredentials)();
|
|
9
|
+
log(had ? "Logged out." : "No active session — credentials already cleared.");
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":";;AAMA,sCAKC;AAXD,sCAAgE;AAMzD,KAAK,UAAU,aAAa,CAAC,OAAsB,EAAE;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,IAAA,sBAAe,GAAE,CAAC;IACpC,MAAM,IAAA,uBAAgB,GAAE,CAAC;IACzB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kDAAkD,CAAC,CAAC;AAChF,CAAC"}
|