@tom2012/cc-web 2026.4.22-c → 2026.4.23-a
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 +1 -1
- package/backend/dist/adapters/claude/scheduled.d.ts +34 -0
- package/backend/dist/adapters/claude/scheduled.d.ts.map +1 -0
- package/backend/dist/adapters/claude/scheduled.js +161 -0
- package/backend/dist/adapters/claude/scheduled.js.map +1 -0
- package/backend/dist/routes/claude.d.ts.map +1 -1
- package/backend/dist/routes/claude.js +36 -0
- package/backend/dist/routes/claude.js.map +1 -1
- package/backend/package-lock.json +22 -0
- package/backend/package.json +1 -0
- package/frontend/dist/assets/{AssistantMessageContent-D9UiFFE2.js → AssistantMessageContent-D2JNDs8w.js} +2 -2
- package/frontend/dist/assets/{GraphPreview-MfS2qFbu.js → GraphPreview-DpuJEzth.js} +1 -1
- package/frontend/dist/assets/{MobilePage-C32pb6m8.js → MobilePage-B792gp0X.js} +4 -4
- package/frontend/dist/assets/{OfficePreview-BTOmTUcw.js → OfficePreview-C8HL3vEN.js} +2 -2
- package/frontend/dist/assets/{ProjectPage-Dhxpa8db.js → ProjectPage-DlWKUSU3.js} +5 -5
- package/frontend/dist/assets/{SettingsPage-ChzjDTNX.js → SettingsPage-TaS0tYXB.js} +2 -2
- package/frontend/dist/assets/{SkillHubPage-DKtZOrUk.js → SkillHubPage-GoI2aP2e.js} +1 -1
- package/frontend/dist/assets/{chevron-down-CDoIuDnn.js → chevron-down-URrZnLx2.js} +1 -1
- package/frontend/dist/assets/{chevron-up-jGWs6GMh.js → chevron-up-Ccf_C2EF.js} +1 -1
- package/frontend/dist/assets/index-90r7D6Jk.css +1 -0
- package/frontend/dist/assets/{index-DqgIuQ6k.js → index-DM6GEXje.js} +1 -1
- package/frontend/dist/assets/{index-CPwZI53Z.js → index-DlOcfeB3.js} +4 -4
- package/frontend/dist/assets/{index-D7HRanYr.js → index-n3xnBH7Z.js} +1 -1
- package/frontend/dist/assets/{jszip.min-BRHGpQBe.js → jszip.min-C0v_rPX3.js} +1 -1
- package/frontend/dist/assets/{search-DM1GyKez.js → search-BDg9Ra4d.js} +1 -1
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-t3Zp9UzI.css +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A self-hosted web application (distributed as npm package) that provides a browser-based interface for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions. Create projects, each with a persistent terminal running Claude Code, and interact with them through a real-time terminal UI.
|
|
4
4
|
|
|
5
|
-
**Current version**: v2026.4.
|
|
5
|
+
**Current version**: v2026.4.23-a | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code CLI scheduled-tasks reader.
|
|
3
|
+
*
|
|
4
|
+
* Reads `~/.claude/scheduled_tasks.json` (durable /loop tasks Claude wrote
|
|
5
|
+
* via CronCreate / ScheduleWakeup with `durable: true`) and filters to the
|
|
6
|
+
* tasks whose originating session's cwd matches a given project folderPath.
|
|
7
|
+
*
|
|
8
|
+
* Claude CLI path / schema reverse-engineered from v2.1.117 Mach-O binary
|
|
9
|
+
* (see research/scheduled-wakeup-panel-plan.md). Session-only tasks are
|
|
10
|
+
* invisible here — they live in CLI process memory, never hit disk.
|
|
11
|
+
*/
|
|
12
|
+
export interface RawScheduledTask {
|
|
13
|
+
id: string;
|
|
14
|
+
cron: string;
|
|
15
|
+
prompt: string;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
recurring?: boolean;
|
|
18
|
+
agentId?: string;
|
|
19
|
+
createdBySessionId?: string;
|
|
20
|
+
createdByPid?: number;
|
|
21
|
+
lastFiredAt?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ScheduledTask extends RawScheduledTask {
|
|
24
|
+
nextFireAt: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function loadScheduledTasks(): RawScheduledTask[];
|
|
27
|
+
/**
|
|
28
|
+
* Return scheduled tasks whose originating session's cwd === folderPath.
|
|
29
|
+
* Tasks without `createdBySessionId` (agent/headless-created, rare) are
|
|
30
|
+
* excluded — we can't attribute them. Tasks whose session has exited
|
|
31
|
+
* (stale sessions file cleanup) are also excluded, by design.
|
|
32
|
+
*/
|
|
33
|
+
export declare function tasksForProject(folderPath: string): ScheduledTask[];
|
|
34
|
+
//# sourceMappingURL=scheduled.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduled.d.ts","sourceRoot":"","sources":["../../../src/adapters/claude/scheduled.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,IAAI,gBAAgB,EAAE,CAmBvD;AA8DD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE,CAgBnE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code CLI scheduled-tasks reader.
|
|
4
|
+
*
|
|
5
|
+
* Reads `~/.claude/scheduled_tasks.json` (durable /loop tasks Claude wrote
|
|
6
|
+
* via CronCreate / ScheduleWakeup with `durable: true`) and filters to the
|
|
7
|
+
* tasks whose originating session's cwd matches a given project folderPath.
|
|
8
|
+
*
|
|
9
|
+
* Claude CLI path / schema reverse-engineered from v2.1.117 Mach-O binary
|
|
10
|
+
* (see research/scheduled-wakeup-panel-plan.md). Session-only tasks are
|
|
11
|
+
* invisible here — they live in CLI process memory, never hit disk.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.loadScheduledTasks = loadScheduledTasks;
|
|
48
|
+
exports.tasksForProject = tasksForProject;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const os = __importStar(require("os"));
|
|
52
|
+
const cron_parser_1 = require("cron-parser");
|
|
53
|
+
const logger_1 = require("../../logger");
|
|
54
|
+
const log = (0, logger_1.modLogger)('scheduled');
|
|
55
|
+
const SCHEDULED_FILE = path.join(os.homedir(), '.claude', 'scheduled_tasks.json');
|
|
56
|
+
const SESSIONS_DIR = path.join(os.homedir(), '.claude', 'sessions');
|
|
57
|
+
function loadScheduledTasks() {
|
|
58
|
+
try {
|
|
59
|
+
if (!fs.existsSync(SCHEDULED_FILE))
|
|
60
|
+
return [];
|
|
61
|
+
const raw = fs.readFileSync(SCHEDULED_FILE, 'utf-8');
|
|
62
|
+
const parsed = JSON.parse(raw);
|
|
63
|
+
if (!Array.isArray(parsed)) {
|
|
64
|
+
log.warn({ file: SCHEDULED_FILE }, 'scheduled_tasks.json is not an array');
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
return parsed.filter((t) => !!t && typeof t === 'object' && typeof t.id === 'string' &&
|
|
68
|
+
typeof t.cron === 'string' &&
|
|
69
|
+
typeof t.prompt === 'string');
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
log.warn({ err, file: SCHEDULED_FILE }, 'failed to read scheduled_tasks.json');
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Canonicalize an on-disk path for equality comparison: resolve symlinks +
|
|
78
|
+
* normalize. Falls back to `path.resolve` if realpath fails (e.g., the path
|
|
79
|
+
* no longer exists because the session's cwd was deleted). Without this
|
|
80
|
+
* `Project.folderPath` (stored raw at create-time) and the CLI's captured
|
|
81
|
+
* `cwd` can differ by trailing slash / symlink even when semantically equal.
|
|
82
|
+
*/
|
|
83
|
+
function canonicalizePath(p) {
|
|
84
|
+
try {
|
|
85
|
+
return fs.realpathSync(p);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return path.resolve(p);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Build a sessionId → canonical-cwd index by scanning `~/.claude/sessions/*.json`.
|
|
93
|
+
* Files are named by PID, so we have to open each one. Cheap in practice
|
|
94
|
+
* (O(few dozen), small JSON), and this is called at most once per request.
|
|
95
|
+
*/
|
|
96
|
+
function buildSessionCwdIndex() {
|
|
97
|
+
const index = new Map();
|
|
98
|
+
try {
|
|
99
|
+
if (!fs.existsSync(SESSIONS_DIR))
|
|
100
|
+
return index;
|
|
101
|
+
const files = fs.readdirSync(SESSIONS_DIR);
|
|
102
|
+
for (const f of files) {
|
|
103
|
+
if (!f.endsWith('.json'))
|
|
104
|
+
continue;
|
|
105
|
+
try {
|
|
106
|
+
const raw = fs.readFileSync(path.join(SESSIONS_DIR, f), 'utf-8');
|
|
107
|
+
const meta = JSON.parse(raw);
|
|
108
|
+
if (meta.sessionId && meta.cwd)
|
|
109
|
+
index.set(meta.sessionId, canonicalizePath(meta.cwd));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// per-file parse failure is non-fatal; skip
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
log.warn({ err, dir: SESSIONS_DIR }, 'failed to scan sessions dir');
|
|
118
|
+
}
|
|
119
|
+
return index;
|
|
120
|
+
}
|
|
121
|
+
function computeNextFire(cron, fromHint) {
|
|
122
|
+
// We want the next FUTURE fire. If the hint (lastFiredAt or createdAt) is
|
|
123
|
+
// in the past (because the creator process died or the file is stale),
|
|
124
|
+
// starting cron-parser from it would return an already-past date. Clamp
|
|
125
|
+
// to now so we always show a forward-looking timestamp.
|
|
126
|
+
const start = Math.max(fromHint, Date.now());
|
|
127
|
+
try {
|
|
128
|
+
const it = cron_parser_1.CronExpressionParser.parse(cron, { currentDate: new Date(start) });
|
|
129
|
+
return it.next().toDate().toISOString();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Return scheduled tasks whose originating session's cwd === folderPath.
|
|
137
|
+
* Tasks without `createdBySessionId` (agent/headless-created, rare) are
|
|
138
|
+
* excluded — we can't attribute them. Tasks whose session has exited
|
|
139
|
+
* (stale sessions file cleanup) are also excluded, by design.
|
|
140
|
+
*/
|
|
141
|
+
function tasksForProject(folderPath) {
|
|
142
|
+
const all = loadScheduledTasks();
|
|
143
|
+
if (all.length === 0)
|
|
144
|
+
return [];
|
|
145
|
+
const idx = buildSessionCwdIndex();
|
|
146
|
+
const targetCwd = canonicalizePath(folderPath);
|
|
147
|
+
const out = [];
|
|
148
|
+
for (const t of all) {
|
|
149
|
+
if (!t.createdBySessionId)
|
|
150
|
+
continue;
|
|
151
|
+
const cwd = idx.get(t.createdBySessionId);
|
|
152
|
+
if (cwd !== targetCwd)
|
|
153
|
+
continue;
|
|
154
|
+
out.push({
|
|
155
|
+
...t,
|
|
156
|
+
nextFireAt: computeNextFire(t.cron, t.lastFiredAt ?? t.createdAt),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=scheduled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduled.js","sourceRoot":"","sources":["../../../src/adapters/claude/scheduled.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/routes/claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/routes/claude.ts"],"names":[],"mappings":"AAmBA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAmIxB,eAAe,MAAM,CAAC"}
|
|
@@ -40,6 +40,7 @@ const os = __importStar(require("os"));
|
|
|
40
40
|
const adapters_1 = require("../adapters");
|
|
41
41
|
const config_1 = require("../config");
|
|
42
42
|
const config_2 = require("../config");
|
|
43
|
+
const scheduled_1 = require("../adapters/claude/scheduled");
|
|
43
44
|
const VALID_TOOLS = ['claude', 'opencode', 'codex', 'qwen', 'gemini', 'terminal'];
|
|
44
45
|
function parseTool(req) {
|
|
45
46
|
const raw = req.query.tool;
|
|
@@ -144,5 +145,40 @@ router.get('/skills', (req, res) => {
|
|
|
144
145
|
const skills = adapter.getSkills(projectPath);
|
|
145
146
|
res.json(skills ?? { builtin: [], custom: [], mcp: [] });
|
|
146
147
|
});
|
|
148
|
+
/**
|
|
149
|
+
* GET /scheduled?projectId=X
|
|
150
|
+
*
|
|
151
|
+
* Reads `~/.claude/scheduled_tasks.json` and returns the subset of tasks
|
|
152
|
+
* whose originating session's cwd matches this project's folderPath. Only
|
|
153
|
+
* `durable: true` tasks live in that file — session-only /loop jobs are
|
|
154
|
+
* invisible (they exist only in Claude CLI process memory).
|
|
155
|
+
*
|
|
156
|
+
* Claude-only: Codex / Gemini / OpenCode / Qwen have no equivalent.
|
|
157
|
+
*/
|
|
158
|
+
router.get('/scheduled', (req, res) => {
|
|
159
|
+
const tool = parseTool(req);
|
|
160
|
+
if (tool !== 'claude') {
|
|
161
|
+
res.status(400).json({ error: 'Scheduled tasks are only available for the claude adapter' });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const projectId = typeof req.query.projectId === 'string' ? req.query.projectId : undefined;
|
|
165
|
+
if (!projectId) {
|
|
166
|
+
res.status(400).json({ error: 'projectId required' });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const project = (0, config_1.getProject)(projectId);
|
|
170
|
+
if (!project) {
|
|
171
|
+
res.status(404).json({ error: 'Project not found' });
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const username = req.user?.username;
|
|
175
|
+
const shared = project.shares?.some((s) => s.username === username);
|
|
176
|
+
if (!(0, config_1.isProjectOwner)(project, username) && !shared) {
|
|
177
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const tasks = (0, scheduled_1.tasksForProject)(project.folderPath);
|
|
181
|
+
res.json({ tasks });
|
|
182
|
+
});
|
|
147
183
|
exports.default = router;
|
|
148
184
|
//# sourceMappingURL=claude.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/routes/claude.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAA2C;AAC3C,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,0CAAyC;AACzC,sCAAuD;AACvD,sCAA4C;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/routes/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"adm-zip": "^0.5.16",
|
|
16
16
|
"bcryptjs": "^2.4.3",
|
|
17
17
|
"cors": "^2.8.5",
|
|
18
|
+
"cron-parser": "^5.5.0",
|
|
18
19
|
"dropbox": "^10.34.0",
|
|
19
20
|
"express": "^4.18.2",
|
|
20
21
|
"googleapis": "^168.0.0",
|
|
@@ -852,6 +853,18 @@
|
|
|
852
853
|
"dev": true,
|
|
853
854
|
"license": "MIT"
|
|
854
855
|
},
|
|
856
|
+
"node_modules/cron-parser": {
|
|
857
|
+
"version": "5.5.0",
|
|
858
|
+
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-5.5.0.tgz",
|
|
859
|
+
"integrity": "sha512-oML4lKUXxizYswqmxuOCpgFS8BNUJpIu6k/2HVHyaL8Ynnf3wdf9tkns0yRdJLSIjkJ+b0DXHMZEHGpMwjnPww==",
|
|
860
|
+
"license": "MIT",
|
|
861
|
+
"dependencies": {
|
|
862
|
+
"luxon": "^3.7.1"
|
|
863
|
+
},
|
|
864
|
+
"engines": {
|
|
865
|
+
"node": ">=18"
|
|
866
|
+
}
|
|
867
|
+
},
|
|
855
868
|
"node_modules/data-uri-to-buffer": {
|
|
856
869
|
"version": "4.0.1",
|
|
857
870
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
|
@@ -1752,6 +1765,15 @@
|
|
|
1752
1765
|
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
|
1753
1766
|
"license": "MIT"
|
|
1754
1767
|
},
|
|
1768
|
+
"node_modules/luxon": {
|
|
1769
|
+
"version": "3.7.2",
|
|
1770
|
+
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
|
|
1771
|
+
"integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
|
|
1772
|
+
"license": "MIT",
|
|
1773
|
+
"engines": {
|
|
1774
|
+
"node": ">=12"
|
|
1775
|
+
}
|
|
1776
|
+
},
|
|
1755
1777
|
"node_modules/make-error": {
|
|
1756
1778
|
"version": "1.3.6",
|
|
1757
1779
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|